mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-10-29 19:34:47 +00:00
input: Add fully configurable trackpad gestures (#11490)
Adds configurable trackpad gestures
This commit is contained in:
parent
378e130f14
commit
81bf4eccba
@ -203,10 +203,8 @@ input {
|
||||
}
|
||||
}
|
||||
|
||||
# https://wiki.hypr.land/Configuring/Variables/#gestures
|
||||
gestures {
|
||||
workspace_swipe = false
|
||||
}
|
||||
# See https://wiki.hypr.land/Configuring/Gestures
|
||||
gesture = 3, horizontal, workspace
|
||||
|
||||
# Example per-device config
|
||||
# See https://wiki.hypr.land/Configuring/Keywords/#per-device-input-configs for more
|
||||
|
||||
@ -9,11 +9,14 @@
|
||||
#include <src/layout/IHyprLayout.hpp>
|
||||
#include <src/managers/LayoutManager.hpp>
|
||||
#include <src/managers/input/InputManager.hpp>
|
||||
#include <src/managers/input/trackpad/TrackpadGestures.hpp>
|
||||
#include <src/Compositor.hpp>
|
||||
#undef private
|
||||
|
||||
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||
#include <hyprutils/string/VarList.hpp>
|
||||
using namespace Hyprutils::Utils;
|
||||
using namespace Hyprutils::String;
|
||||
|
||||
#include "globals.hpp"
|
||||
|
||||
@ -88,6 +91,41 @@ class CTestKeyboard : public IKeyboard {
|
||||
bool m_isVirtual;
|
||||
};
|
||||
|
||||
static SDispatchResult pressAlt(std::string in) {
|
||||
g_pInputManager->m_lastMods = in == "1" ? HL_MODIFIER_ALT : 0;
|
||||
|
||||
return {.success = true};
|
||||
}
|
||||
|
||||
static SDispatchResult simulateGesture(std::string in) {
|
||||
CVarList data(in);
|
||||
|
||||
uint32_t fingers = 3;
|
||||
try {
|
||||
fingers = std::stoul(data[1]);
|
||||
} catch (...) { return {.success = false}; }
|
||||
|
||||
if (data[0] == "down") {
|
||||
g_pTrackpadGestures->gestureBegin(IPointer::SSwipeBeginEvent{});
|
||||
g_pTrackpadGestures->gestureUpdate(IPointer::SSwipeUpdateEvent{.fingers = fingers, .delta = {0, 300}});
|
||||
g_pTrackpadGestures->gestureEnd(IPointer::SSwipeEndEvent{});
|
||||
} else if (data[0] == "up") {
|
||||
g_pTrackpadGestures->gestureBegin(IPointer::SSwipeBeginEvent{});
|
||||
g_pTrackpadGestures->gestureUpdate(IPointer::SSwipeUpdateEvent{.fingers = fingers, .delta = {0, -300}});
|
||||
g_pTrackpadGestures->gestureEnd(IPointer::SSwipeEndEvent{});
|
||||
} else if (data[0] == "left") {
|
||||
g_pTrackpadGestures->gestureBegin(IPointer::SSwipeBeginEvent{});
|
||||
g_pTrackpadGestures->gestureUpdate(IPointer::SSwipeUpdateEvent{.fingers = fingers, .delta = {-300, 0}});
|
||||
g_pTrackpadGestures->gestureEnd(IPointer::SSwipeEndEvent{});
|
||||
} else {
|
||||
g_pTrackpadGestures->gestureBegin(IPointer::SSwipeBeginEvent{});
|
||||
g_pTrackpadGestures->gestureUpdate(IPointer::SSwipeUpdateEvent{.fingers = fingers, .delta = {300, 0}});
|
||||
g_pTrackpadGestures->gestureEnd(IPointer::SSwipeEndEvent{});
|
||||
}
|
||||
|
||||
return {.success = true};
|
||||
}
|
||||
|
||||
static SDispatchResult vkb(std::string in) {
|
||||
auto tkb0 = CTestKeyboard::create(false);
|
||||
auto tkb1 = CTestKeyboard::create(false);
|
||||
@ -141,6 +179,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:test", ::test);
|
||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:snapmove", ::snapMove);
|
||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:vkb", ::vkb);
|
||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:alt", ::pressAlt);
|
||||
HyprlandAPI::addDispatcherV2(PHANDLE, "plugin:test:gesture", ::simulateGesture);
|
||||
|
||||
return {"hyprtestplugin", "hyprtestplugin", "Vaxry", "1.0"};
|
||||
}
|
||||
|
||||
155
hyprtester/src/tests/main/gestures.cpp
Normal file
155
hyprtester/src/tests/main/gestures.cpp
Normal file
@ -0,0 +1,155 @@
|
||||
#include "tests.hpp"
|
||||
#include "../../shared.hpp"
|
||||
#include "../../hyprctlCompat.hpp"
|
||||
#include <print>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <hyprutils/os/Process.hpp>
|
||||
#include <hyprutils/memory/WeakPtr.hpp>
|
||||
#include <csignal>
|
||||
#include <cerrno>
|
||||
#include "../shared.hpp"
|
||||
|
||||
static int ret = 0;
|
||||
|
||||
using namespace Hyprutils::OS;
|
||||
using namespace Hyprutils::Memory;
|
||||
|
||||
#define UP CUniquePointer
|
||||
#define SP CSharedPointer
|
||||
|
||||
static bool test() {
|
||||
NLog::log("{}Testing gestures", Colors::GREEN);
|
||||
|
||||
EXPECT(Tests::windowCount(), 0);
|
||||
|
||||
// test on workspace "window"
|
||||
NLog::log("{}Switching to workspace 1", Colors::YELLOW);
|
||||
getFromSocket("/dispatch workspace 1"); // no OK: we might be on 1 already
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture left,3"));
|
||||
|
||||
// wait while kitty spawns
|
||||
int counter = 0;
|
||||
while (Tests::windowCount() != 1) {
|
||||
counter++;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
if (counter > 50) {
|
||||
NLog::log("{}Gesture didnt spawn kitty", Colors::RED);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT(Tests::windowCount(), 1);
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture right,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/clients");
|
||||
EXPECT_CONTAINS(str, "floating: 1");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture down,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/clients");
|
||||
EXPECT_CONTAINS(str, "fullscreen: 2");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture down,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/clients");
|
||||
EXPECT_CONTAINS(str, "fullscreen: 0");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:alt 1"));
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture left,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/workspaces");
|
||||
EXPECT_CONTAINS(str, "ID 2 (2)");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture right,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/workspaces");
|
||||
EXPECT_NOT_CONTAINS(str, "ID 2 (2)");
|
||||
}
|
||||
|
||||
// check for crashes
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture right,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/workspaces");
|
||||
EXPECT_NOT_CONTAINS(str, "ID 2 (2)");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/keyword gestures:workspace_swipe_invert 0"));
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture right,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/workspaces");
|
||||
EXPECT_CONTAINS(str, "ID 2 (2)");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture left,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/workspaces");
|
||||
EXPECT_NOT_CONTAINS(str, "ID 2 (2)");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/keyword gestures:workspace_swipe_invert 1"));
|
||||
OK(getFromSocket("/keyword gestures:workspace_swipe_create_new 0"));
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture left,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/workspaces");
|
||||
EXPECT_NOT_CONTAINS(str, "ID 2 (2)");
|
||||
EXPECT_CONTAINS(str, "ID 1 (1)");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture down,3"));
|
||||
|
||||
{
|
||||
auto str = getFromSocket("/clients");
|
||||
EXPECT_CONTAINS(str, "floating: 0");
|
||||
}
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:alt 0"));
|
||||
|
||||
OK(getFromSocket("/dispatch plugin:test:gesture up,3"));
|
||||
|
||||
counter = 0;
|
||||
while (Tests::windowCount() != 0) {
|
||||
counter++;
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
if (counter > 50) {
|
||||
NLog::log("{}Gesture didnt close kitty", Colors::RED);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT(Tests::windowCount(), 0);
|
||||
|
||||
// kill all
|
||||
NLog::log("{}Killing all windows", Colors::YELLOW);
|
||||
Tests::killAllWindows();
|
||||
|
||||
NLog::log("{}Expecting 0 windows", Colors::YELLOW);
|
||||
EXPECT(Tests::windowCount(), 0);
|
||||
|
||||
// reload cfg
|
||||
OK(getFromSocket("/reload"));
|
||||
|
||||
return !ret;
|
||||
}
|
||||
|
||||
REGISTER_TEST_FN(test)
|
||||
@ -203,7 +203,7 @@ input {
|
||||
|
||||
# https://wiki.hyprland.org/Configuring/Variables/#gestures
|
||||
gestures {
|
||||
workspace_swipe = false
|
||||
|
||||
}
|
||||
|
||||
# Example per-device config
|
||||
@ -313,3 +313,13 @@ windowrulev2 = bordersize 0, floating:0, onworkspace:n[s:window] w[tv1]
|
||||
windowrulev2 = rounding 0, floating:0, onworkspace:n[s:window] w[tv1]
|
||||
windowrulev2 = bordersize 0, floating:0, onworkspace:n[s:window] f[1]
|
||||
windowrulev2 = rounding 0, floating:0, onworkspace:n[s:window] f[1]
|
||||
|
||||
gesture = 3, left, dispatcher, exec, kitty
|
||||
gesture = 3, right, float
|
||||
gesture = 3, up, close
|
||||
gesture = 3, down, fullscreen
|
||||
|
||||
gesture = 3, down, mod:ALT, float
|
||||
|
||||
gesture = 3, horizontal, mod:ALT, workspace
|
||||
|
||||
|
||||
@ -23,8 +23,13 @@ in {
|
||||
"HYPRLAND_TRACE" = "1";
|
||||
"XDG_RUNTIME_DIR" = "/tmp";
|
||||
"XDG_CACHE_HOME" = "/tmp";
|
||||
"KITTY_CONFIG_DIRECTORY" = "/etc/kitty";
|
||||
};
|
||||
|
||||
environment.etc."kitty/kitty.conf".text = ''
|
||||
confirm_os_window_close 0
|
||||
'';
|
||||
|
||||
programs.hyprland = {
|
||||
enable = true;
|
||||
package = hyprland;
|
||||
|
||||
@ -53,7 +53,8 @@
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "render/OpenGL.hpp"
|
||||
#include "managers/input/InputManager.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/animation/AnimationManager.hpp"
|
||||
#include "managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "managers/EventManager.hpp"
|
||||
#include "managers/HookSystemManager.hpp"
|
||||
#include "managers/ProtocolManager.hpp"
|
||||
@ -2035,8 +2036,10 @@ void CCompositor::swapActiveWorkspaces(PHLMONITOR pMonitorA, PHLMONITOR pMonitor
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitorA->m_id);
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitorB->m_id);
|
||||
|
||||
updateFullscreenFadeOnWorkspace(PWORKSPACEB);
|
||||
updateFullscreenFadeOnWorkspace(PWORKSPACEA);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
PWORKSPACEB, PWORKSPACEB->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
PWORKSPACEA, PWORKSPACEA->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
|
||||
if (pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id || pMonitorB->m_id == g_pCompositor->m_lastMonitor->m_id) {
|
||||
const auto LASTWIN = pMonitorA->m_id == g_pCompositor->m_lastMonitor->m_id ? PWORKSPACEB->getLastFocusedWindow() : PWORKSPACEA->getLastFocusedWindow();
|
||||
@ -2221,7 +2224,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
|
||||
|
||||
if (valid(pMonitor->m_activeWorkspace)) {
|
||||
pMonitor->m_activeWorkspace->m_visible = false;
|
||||
pMonitor->m_activeWorkspace->startAnim(false, false);
|
||||
g_pDesktopAnimationManager->startAnimation(pWorkspace, CDesktopAnimationManager::ANIMATION_TYPE_OUT, false);
|
||||
}
|
||||
|
||||
if (*PHIDESPECIALONWORKSPACECHANGE)
|
||||
@ -2239,7 +2242,7 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(pMonitor->m_id);
|
||||
|
||||
pWorkspace->startAnim(true, true, true);
|
||||
g_pDesktopAnimationManager->startAnimation(pWorkspace, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
|
||||
pWorkspace->m_visible = true;
|
||||
|
||||
if (!noWarpCursor)
|
||||
@ -2252,11 +2255,14 @@ void CCompositor::moveWorkspaceToMonitor(PHLWORKSPACE pWorkspace, PHLMONITOR pMo
|
||||
if (POLDMON) {
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(POLDMON->m_id);
|
||||
if (valid(POLDMON->m_activeWorkspace))
|
||||
updateFullscreenFadeOnWorkspace(POLDMON->m_activeWorkspace);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(POLDMON->m_activeWorkspace,
|
||||
POLDMON->m_activeWorkspace->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN :
|
||||
CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
updateSuspendedStates();
|
||||
}
|
||||
|
||||
updateFullscreenFadeOnWorkspace(pWorkspace);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
pWorkspace, pWorkspace->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
updateSuspendedStates();
|
||||
|
||||
// event
|
||||
@ -2279,36 +2285,6 @@ bool CCompositor::workspaceIDOutOfBounds(const WORKSPACEID& id) {
|
||||
return std::clamp(id, lowestID, highestID) != id;
|
||||
}
|
||||
|
||||
void CCompositor::updateFullscreenFadeOnWorkspace(PHLWORKSPACE pWorkspace) {
|
||||
|
||||
if (!pWorkspace)
|
||||
return;
|
||||
|
||||
const auto FULLSCREEN = pWorkspace->m_hasFullscreenWindow;
|
||||
|
||||
for (auto const& w : g_pCompositor->m_windows) {
|
||||
if (w->m_workspace == pWorkspace) {
|
||||
|
||||
if (w->m_fadingOut || w->m_pinned || w->isFullscreen())
|
||||
continue;
|
||||
|
||||
if (!FULLSCREEN)
|
||||
*w->m_alpha = 1.f;
|
||||
else if (!w->isFullscreen())
|
||||
*w->m_alpha = !w->m_createdOverFullscreen ? 0.f : 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
const auto PMONITOR = pWorkspace->m_monitor.lock();
|
||||
|
||||
if (pWorkspace->m_id == PMONITOR->activeWorkspaceID() || pWorkspace->m_id == PMONITOR->activeSpecialWorkspaceID()) {
|
||||
for (auto const& ls : PMONITOR->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
if (!ls->m_fadingOut)
|
||||
*ls->m_alpha = FULLSCREEN && pWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCompositor::changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON) {
|
||||
setWindowFullscreenClient(
|
||||
PWINDOW,
|
||||
@ -2396,7 +2372,8 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS
|
||||
w->m_createdOverFullscreen = false;
|
||||
}
|
||||
|
||||
updateFullscreenFadeOnWorkspace(PWORKSPACE);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
PWORKSPACE, PWORKSPACE->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
|
||||
PWINDOW->sendWindowSize(true);
|
||||
|
||||
|
||||
@ -138,7 +138,6 @@ class CCompositor {
|
||||
void setWindowFullscreenClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE);
|
||||
void setWindowFullscreenState(const PHLWINDOW PWINDOW, const SFullscreenState state);
|
||||
void changeWindowFullscreenModeClient(const PHLWINDOW PWINDOW, const eFullscreenMode MODE, const bool ON);
|
||||
void updateFullscreenFadeOnWorkspace(PHLWORKSPACE);
|
||||
PHLWINDOW getX11Parent(PHLWINDOW);
|
||||
void scheduleFrameForMonitor(PHLMONITOR, Aquamarine::IOutput::scheduleFrameReason reason = Aquamarine::IOutput::AQ_SCHEDULE_CLIENT_UNKNOWN);
|
||||
void addToFadingOutSafe(PHLLS);
|
||||
|
||||
@ -763,24 +763,6 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
* gestures:
|
||||
*/
|
||||
|
||||
SConfigOptionDescription{
|
||||
.value = "gestures:workspace_swipe",
|
||||
.description = "enable workspace swipe gesture on touchpad",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "gestures:workspace_swipe_fingers",
|
||||
.description = "how many fingers for the touchpad gesture",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{3, 0, 5}, //##TODO RANGE?
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "gestures:workspace_swipe_min_fingers",
|
||||
.description = "if enabled, workspace_swipe_fingers is considered the minimum number of fingers to swipe",
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "gestures:workspace_swipe_distance",
|
||||
.description = "in px, the distance of the touchpad gesture",
|
||||
@ -847,6 +829,12 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
||||
.type = CONFIG_OPTION_BOOL,
|
||||
.data = SConfigOptionDescription::SBoolData{false},
|
||||
},
|
||||
SConfigOptionDescription{
|
||||
.value = "gestures:close_max_timeout",
|
||||
.description = "Timeout for closing windows with the close gesture, in ms.",
|
||||
.type = CONFIG_OPTION_INT,
|
||||
.data = SConfigOptionDescription::SRangeData{1000, 10, 2000},
|
||||
},
|
||||
|
||||
/*
|
||||
* group:
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../xwayland/XWayland.hpp"
|
||||
#include "../protocols/OutputManagement.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "defaultConfig.hpp"
|
||||
|
||||
@ -26,6 +26,16 @@
|
||||
#include "../debug/HyprNotificationOverlay.hpp"
|
||||
#include "../plugins/PluginSystem.hpp"
|
||||
|
||||
#include "../managers/input/trackpad/TrackpadGestures.hpp"
|
||||
#include "../managers/input/trackpad/gestures/DispatcherGesture.hpp"
|
||||
#include "../managers/input/trackpad/gestures/WorkspaceSwipeGesture.hpp"
|
||||
#include "../managers/input/trackpad/gestures/ResizeGesture.hpp"
|
||||
#include "../managers/input/trackpad/gestures/MoveGesture.hpp"
|
||||
#include "../managers/input/trackpad/gestures/SpecialWorkspaceGesture.hpp"
|
||||
#include "../managers/input/trackpad/gestures/CloseGesture.hpp"
|
||||
#include "../managers/input/trackpad/gestures/FloatGesture.hpp"
|
||||
#include "../managers/input/trackpad/gestures/FullscreenGesture.hpp"
|
||||
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../protocols/types/ContentType.hpp"
|
||||
#include <cstddef>
|
||||
@ -46,6 +56,7 @@
|
||||
#include <ranges>
|
||||
#include <unordered_set>
|
||||
#include <hyprutils/string/String.hpp>
|
||||
#include <hyprutils/string/ConstVarList.hpp>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
using namespace Hyprutils::String;
|
||||
@ -409,6 +420,18 @@ static Hyprlang::CParseResult handlePermission(const char* c, const char* v) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleGesture(const char* c, const char* v) {
|
||||
const std::string VALUE = v;
|
||||
const std::string COMMAND = c;
|
||||
|
||||
const auto RESULT = g_pConfigManager->handleGesture(COMMAND, VALUE);
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
if (RESULT.has_value())
|
||||
result.setError(RESULT.value().c_str());
|
||||
return result;
|
||||
}
|
||||
|
||||
void CConfigManager::registerConfigVar(const char* name, const Hyprlang::INT& val) {
|
||||
m_configValueNumber++;
|
||||
m_config->addConfigValue(name, val);
|
||||
@ -692,9 +715,6 @@ CConfigManager::CConfigManager() {
|
||||
registerConfigVar("binds:allow_pin_fullscreen", Hyprlang::INT{0});
|
||||
registerConfigVar("binds:drag_threshold", Hyprlang::INT{0});
|
||||
|
||||
registerConfigVar("gestures:workspace_swipe", Hyprlang::INT{0});
|
||||
registerConfigVar("gestures:workspace_swipe_fingers", Hyprlang::INT{3});
|
||||
registerConfigVar("gestures:workspace_swipe_min_fingers", Hyprlang::INT{0});
|
||||
registerConfigVar("gestures:workspace_swipe_distance", Hyprlang::INT{300});
|
||||
registerConfigVar("gestures:workspace_swipe_invert", Hyprlang::INT{1});
|
||||
registerConfigVar("gestures:workspace_swipe_min_speed_to_force", Hyprlang::INT{30});
|
||||
@ -706,6 +726,7 @@ CConfigManager::CConfigManager() {
|
||||
registerConfigVar("gestures:workspace_swipe_use_r", Hyprlang::INT{0});
|
||||
registerConfigVar("gestures:workspace_swipe_touch", Hyprlang::INT{0});
|
||||
registerConfigVar("gestures:workspace_swipe_touch_invert", Hyprlang::INT{0});
|
||||
registerConfigVar("gestures:close_max_timeout", Hyprlang::INT{1000});
|
||||
|
||||
registerConfigVar("xwayland:enabled", Hyprlang::INT{1});
|
||||
registerConfigVar("xwayland:use_nearest_neighbor", Hyprlang::INT{1});
|
||||
@ -846,6 +867,7 @@ CConfigManager::CConfigManager() {
|
||||
m_config->registerHandler(&::handleBlurLS, "blurls", {false});
|
||||
m_config->registerHandler(&::handlePlugin, "plugin", {false});
|
||||
m_config->registerHandler(&::handlePermission, "permission", {false});
|
||||
m_config->registerHandler(&::handleGesture, "gesture", {false});
|
||||
m_config->registerHandler(&::handleEnv, "env", {true});
|
||||
|
||||
// pluginza
|
||||
@ -1029,6 +1051,7 @@ std::optional<std::string> CConfigManager::resetHLConfig() {
|
||||
g_pKeybindManager->clearKeybinds();
|
||||
g_pAnimationManager->removeAllBeziers();
|
||||
g_pAnimationManager->addBezierWithName("linear", Vector2D(0.0, 0.0), Vector2D(1.0, 1.0));
|
||||
g_pTrackpadGestures->clearGestures();
|
||||
|
||||
m_mAdditionalReservedAreas.clear();
|
||||
m_blurLSNamespaces.clear();
|
||||
@ -3149,6 +3172,73 @@ std::optional<std::string> CConfigManager::handlePermission(const std::string& c
|
||||
return {};
|
||||
}
|
||||
|
||||
std::optional<std::string> CConfigManager::handleGesture(const std::string& command, const std::string& value) {
|
||||
CConstVarList data(value);
|
||||
|
||||
size_t fingerCount = 0;
|
||||
eTrackpadGestureDirection direction = TRACKPAD_GESTURE_DIR_NONE;
|
||||
|
||||
try {
|
||||
fingerCount = std::stoul(std::string{data[0]});
|
||||
} catch (...) { return std::format("Invalid value {} for finger count", data[0]); }
|
||||
|
||||
if (fingerCount <= 1 || fingerCount >= 10)
|
||||
return std::format("Invalid value {} for finger count", data[0]);
|
||||
|
||||
direction = g_pTrackpadGestures->dirForString(data[1]);
|
||||
|
||||
if (direction == TRACKPAD_GESTURE_DIR_NONE)
|
||||
return std::format("Invalid direction: {}", data[1]);
|
||||
|
||||
int startDataIdx = 2;
|
||||
uint32_t modMask = 0;
|
||||
float deltaScale = 1.F;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (data[startDataIdx].starts_with("mod:")) {
|
||||
modMask = g_pKeybindManager->stringToModMask(std::string{data[startDataIdx].substr(4)});
|
||||
startDataIdx++;
|
||||
continue;
|
||||
} else if (data[startDataIdx].starts_with("scale:")) {
|
||||
try {
|
||||
deltaScale = std::clamp(std::stof(std::string{data[startDataIdx].substr(6)}), 0.1F, 10.F);
|
||||
startDataIdx++;
|
||||
continue;
|
||||
} catch (...) { return std::format("Invalid delta scale: {}", std::string{data[startDataIdx].substr(6)}); }
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
std::expected<void, std::string> result;
|
||||
|
||||
if (data[startDataIdx] == "dispatcher")
|
||||
result = g_pTrackpadGestures->addGesture(makeUnique<CDispatcherTrackpadGesture>(std::string{data[startDataIdx + 1]}, std::string{data[startDataIdx + 2]}), fingerCount,
|
||||
direction, modMask, deltaScale);
|
||||
else if (data[startDataIdx] == "workspace")
|
||||
result = g_pTrackpadGestures->addGesture(makeUnique<CWorkspaceSwipeGesture>(), fingerCount, direction, modMask, deltaScale);
|
||||
else if (data[startDataIdx] == "resize")
|
||||
result = g_pTrackpadGestures->addGesture(makeUnique<CResizeTrackpadGesture>(), fingerCount, direction, modMask, deltaScale);
|
||||
else if (data[startDataIdx] == "move")
|
||||
result = g_pTrackpadGestures->addGesture(makeUnique<CMoveTrackpadGesture>(), fingerCount, direction, modMask, deltaScale);
|
||||
else if (data[startDataIdx] == "special")
|
||||
result = g_pTrackpadGestures->addGesture(makeUnique<CSpecialWorkspaceGesture>(std::string{data[startDataIdx + 1]}), fingerCount, direction, modMask, deltaScale);
|
||||
else if (data[startDataIdx] == "close")
|
||||
result = g_pTrackpadGestures->addGesture(makeUnique<CCloseTrackpadGesture>(), fingerCount, direction, modMask, deltaScale);
|
||||
else if (data[startDataIdx] == "float")
|
||||
result = g_pTrackpadGestures->addGesture(makeUnique<CFloatTrackpadGesture>(std::string{data[startDataIdx + 1]}), fingerCount, direction, modMask, deltaScale);
|
||||
else if (data[startDataIdx] == "fullscreen")
|
||||
result = g_pTrackpadGestures->addGesture(makeUnique<CFullscreenTrackpadGesture>(std::string{data[startDataIdx + 1]}), fingerCount, direction, modMask, deltaScale);
|
||||
else
|
||||
return std::format("Invalid gesture: {}", data[startDataIdx]);
|
||||
|
||||
if (!result)
|
||||
return result.error();
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::vector<SConfigOptionDescription>& CConfigManager::getAllDescriptions() {
|
||||
return CONFIG_OPTIONS;
|
||||
}
|
||||
|
||||
@ -284,6 +284,7 @@ class CConfigManager {
|
||||
std::optional<std::string> handleEnv(const std::string&, const std::string&);
|
||||
std::optional<std::string> handlePlugin(const std::string&, const std::string&);
|
||||
std::optional<std::string> handlePermission(const std::string&, const std::string&);
|
||||
std::optional<std::string> handleGesture(const std::string&, const std::string&);
|
||||
|
||||
std::optional<std::string> handleMonitorv2(const std::string& output);
|
||||
Hyprlang::CParseResult handleMonitorv2();
|
||||
|
||||
@ -51,7 +51,7 @@ using namespace Hyprutils::OS;
|
||||
#include "../managers/XWaylandManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../plugins/PluginSystem.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../debug/HyprNotificationOverlay.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../render/OpenGL.hpp"
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "../Compositor.hpp"
|
||||
#include "../render/pass/TexPassElement.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
|
||||
CHyprDebugOverlay::CHyprDebugOverlay() {
|
||||
m_texture = makeShared<CTexture>();
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../render/pass/TexPassElement.hpp"
|
||||
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
|
||||
@ -4,7 +4,8 @@
|
||||
#include "../protocols/LayerShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
@ -99,7 +100,7 @@ void CLayerSurface::onDestroy() {
|
||||
} else {
|
||||
Debug::log(LOG, "Removing LayerSurface that wasn't mapped.");
|
||||
if (m_alpha)
|
||||
m_alpha->setValueAndWarp(0.f);
|
||||
g_pDesktopAnimationManager->startAnimation(m_self.lock(), CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
m_fadingOut = true;
|
||||
g_pCompositor->addToFadingOutSafe(m_self.lock());
|
||||
}
|
||||
@ -183,9 +184,9 @@ void CLayerSurface::onMap() {
|
||||
|
||||
CBox geomFixed = {m_geometry.x + PMONITOR->m_position.x, m_geometry.y + PMONITOR->m_position.y, m_geometry.width, m_geometry.height};
|
||||
g_pHyprRenderer->damageBox(geomFixed);
|
||||
const bool FULLSCREEN = PMONITOR->m_activeWorkspace && PMONITOR->m_activeWorkspace->m_hasFullscreenWindow && PMONITOR->m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN;
|
||||
|
||||
startAnimation(!(m_layer == ZWLR_LAYER_SHELL_V1_LAYER_TOP && FULLSCREEN && !GRABSFOCUS));
|
||||
g_pDesktopAnimationManager->startAnimation(m_self.lock(), CDesktopAnimationManager::ANIMATION_TYPE_IN);
|
||||
|
||||
m_readyToDelete = false;
|
||||
m_fadingOut = false;
|
||||
|
||||
@ -213,7 +214,7 @@ void CLayerSurface::onUnmap() {
|
||||
if (m_layerSurface && m_layerSurface->m_surface)
|
||||
m_layerSurface->m_surface->unmap();
|
||||
|
||||
startAnimation(false);
|
||||
g_pDesktopAnimationManager->startAnimation(m_self.lock(), CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -224,7 +225,9 @@ void CLayerSurface::onUnmap() {
|
||||
// make a snapshot and start fade
|
||||
g_pHyprRenderer->makeSnapshot(m_self.lock());
|
||||
|
||||
startAnimation(false);
|
||||
g_pDesktopAnimationManager->startAnimation(m_self.lock(), CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
|
||||
m_fadingOut = true;
|
||||
|
||||
m_mapped = false;
|
||||
if (m_layerSurface && m_layerSurface->m_surface)
|
||||
@ -453,138 +456,6 @@ void CLayerSurface::applyRules() {
|
||||
}
|
||||
}
|
||||
|
||||
void CLayerSurface::startAnimation(bool in, bool instant) {
|
||||
if (in) {
|
||||
m_realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
||||
m_realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
||||
m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"));
|
||||
} else {
|
||||
m_realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
||||
m_realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
||||
m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut"));
|
||||
}
|
||||
|
||||
const auto ANIMSTYLE = m_animationStyle.value_or(m_realPosition->getStyle());
|
||||
if (ANIMSTYLE.starts_with("slide")) {
|
||||
// get closest edge
|
||||
const auto MIDDLE = m_geometry.middle();
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromVector(MIDDLE);
|
||||
|
||||
if (!PMONITOR) { // can rarely happen on exit
|
||||
m_alpha->setValueAndWarp(in ? 1.F : 0.F);
|
||||
return;
|
||||
}
|
||||
|
||||
int force = -1;
|
||||
|
||||
CVarList args(ANIMSTYLE, 0, 's');
|
||||
if (args.size() > 1) {
|
||||
const auto ARG2 = args[1];
|
||||
if (ARG2 == "top")
|
||||
force = 0;
|
||||
else if (ARG2 == "bottom")
|
||||
force = 1;
|
||||
else if (ARG2 == "left")
|
||||
force = 2;
|
||||
else if (ARG2 == "right")
|
||||
force = 3;
|
||||
}
|
||||
|
||||
const std::array<Vector2D, 4> edgePoints = {
|
||||
PMONITOR->m_position + Vector2D{PMONITOR->m_size.x / 2, 0.0},
|
||||
PMONITOR->m_position + Vector2D{PMONITOR->m_size.x / 2, PMONITOR->m_size.y},
|
||||
PMONITOR->m_position + Vector2D{0.0, PMONITOR->m_size.y},
|
||||
PMONITOR->m_position + Vector2D{PMONITOR->m_size.x, PMONITOR->m_size.y / 2},
|
||||
};
|
||||
|
||||
float closest = std::numeric_limits<float>::max();
|
||||
int leader = force;
|
||||
if (leader == -1) {
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
float dist = MIDDLE.distance(edgePoints[i]);
|
||||
if (dist < closest) {
|
||||
leader = i;
|
||||
closest = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_realSize->setValueAndWarp(m_geometry.size());
|
||||
m_alpha->setValueAndWarp(in ? 0.f : 1.f);
|
||||
*m_alpha = in ? 1.f : 0.f;
|
||||
|
||||
Vector2D prePos;
|
||||
|
||||
switch (leader) {
|
||||
case 0:
|
||||
// TOP
|
||||
prePos = {m_geometry.x, PMONITOR->m_position.y - m_geometry.h};
|
||||
break;
|
||||
case 1:
|
||||
// BOTTOM
|
||||
prePos = {m_geometry.x, PMONITOR->m_position.y + PMONITOR->m_size.y};
|
||||
break;
|
||||
case 2:
|
||||
// LEFT
|
||||
prePos = {PMONITOR->m_position.x - m_geometry.w, m_geometry.y};
|
||||
break;
|
||||
case 3:
|
||||
// RIGHT
|
||||
prePos = {PMONITOR->m_position.x + PMONITOR->m_size.x, m_geometry.y};
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
if (in) {
|
||||
m_realPosition->setValueAndWarp(prePos);
|
||||
*m_realPosition = m_geometry.pos();
|
||||
} else {
|
||||
m_realPosition->setValueAndWarp(m_geometry.pos());
|
||||
*m_realPosition = prePos;
|
||||
}
|
||||
|
||||
} else if (ANIMSTYLE.starts_with("popin")) {
|
||||
float minPerc = 0.f;
|
||||
if (ANIMSTYLE.find("%") != std::string::npos) {
|
||||
try {
|
||||
auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' '));
|
||||
minPerc = std::stoi(percstr.substr(0, percstr.length() - 1));
|
||||
} catch (std::exception& e) {
|
||||
; // oops
|
||||
}
|
||||
}
|
||||
|
||||
minPerc *= 0.01;
|
||||
|
||||
const auto GOALSIZE = (m_geometry.size() * minPerc).clamp({5, 5});
|
||||
const auto GOALPOS = m_geometry.pos() + (m_geometry.size() - GOALSIZE) / 2.f;
|
||||
|
||||
m_alpha->setValueAndWarp(in ? 0.f : 1.f);
|
||||
*m_alpha = in ? 1.f : 0.f;
|
||||
|
||||
if (in) {
|
||||
m_realSize->setValueAndWarp(GOALSIZE);
|
||||
m_realPosition->setValueAndWarp(GOALPOS);
|
||||
*m_realSize = m_geometry.size();
|
||||
*m_realPosition = m_geometry.pos();
|
||||
} else {
|
||||
m_realSize->setValueAndWarp(m_geometry.size());
|
||||
m_realPosition->setValueAndWarp(m_geometry.pos());
|
||||
*m_realSize = GOALSIZE;
|
||||
*m_realPosition = GOALPOS;
|
||||
}
|
||||
} else {
|
||||
// fade
|
||||
m_realPosition->setValueAndWarp(m_geometry.pos());
|
||||
m_realSize->setValueAndWarp(m_geometry.size());
|
||||
*m_alpha = in ? 1.f : 0.f;
|
||||
}
|
||||
|
||||
if (!in)
|
||||
m_fadingOut = true;
|
||||
}
|
||||
|
||||
bool CLayerSurface::isFadedOut() {
|
||||
if (!m_fadingOut)
|
||||
return false;
|
||||
|
||||
@ -18,7 +18,6 @@ class CLayerSurface {
|
||||
~CLayerSurface();
|
||||
|
||||
void applyRules();
|
||||
void startAnimation(bool in, bool instant = false);
|
||||
bool isFadedOut();
|
||||
int popupsCount();
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
#include "../managers/SeatManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../managers/TokenManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../managers/ANRManager.hpp"
|
||||
#include "../protocols/XDGShell.hpp"
|
||||
#include "../protocols/core/Compositor.hpp"
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
#include "../Compositor.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "config/ConfigManager.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/animation/AnimationManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
|
||||
@ -75,119 +75,6 @@ CWorkspace::~CWorkspace() {
|
||||
m_events.destroy.emit();
|
||||
}
|
||||
|
||||
void CWorkspace::startAnim(bool in, bool left, bool instant) {
|
||||
if (!instant) {
|
||||
const std::string ANIMNAME = std::format("{}{}", m_isSpecialWorkspace ? "specialWorkspace" : "workspaces", in ? "In" : "Out");
|
||||
|
||||
m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig(ANIMNAME));
|
||||
m_renderOffset->setConfig(g_pConfigManager->getAnimationPropertyConfig(ANIMNAME));
|
||||
}
|
||||
|
||||
const auto ANIMSTYLE = m_alpha->getStyle();
|
||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||
|
||||
// set floating windows offset callbacks
|
||||
m_renderOffset->setUpdateCallback([&](auto) {
|
||||
for (auto const& w : g_pCompositor->m_windows) {
|
||||
if (!validMapped(w) || w->workspaceID() != m_id)
|
||||
continue;
|
||||
|
||||
w->onWorkspaceAnimUpdate();
|
||||
};
|
||||
});
|
||||
|
||||
if (ANIMSTYLE.starts_with("slidefade")) {
|
||||
const auto PMONITOR = m_monitor.lock();
|
||||
float movePerc = 100.f;
|
||||
|
||||
if (ANIMSTYLE.find('%') != std::string::npos) {
|
||||
try {
|
||||
auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' ') + 1);
|
||||
movePerc = std::stoi(percstr.substr(0, percstr.length() - 1));
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Error in startAnim: invalid percentage"); }
|
||||
}
|
||||
|
||||
m_alpha->setValueAndWarp(1.f);
|
||||
m_renderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
|
||||
if (ANIMSTYLE.starts_with("slidefadevert")) {
|
||||
if (in) {
|
||||
m_alpha->setValueAndWarp(0.f);
|
||||
m_renderOffset->setValueAndWarp(Vector2D(0.0, (left ? PMONITOR->m_size.y : -PMONITOR->m_size.y) * (movePerc / 100.f)));
|
||||
*m_alpha = 1.f;
|
||||
*m_renderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
m_alpha->setValueAndWarp(1.f);
|
||||
*m_alpha = 0.f;
|
||||
*m_renderOffset = Vector2D(0.0, (left ? -PMONITOR->m_size.y : PMONITOR->m_size.y) * (movePerc / 100.f));
|
||||
}
|
||||
} else {
|
||||
if (in) {
|
||||
m_alpha->setValueAndWarp(0.f);
|
||||
m_renderOffset->setValueAndWarp(Vector2D((left ? PMONITOR->m_size.x : -PMONITOR->m_size.x) * (movePerc / 100.f), 0.0));
|
||||
*m_alpha = 1.f;
|
||||
*m_renderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
m_alpha->setValueAndWarp(1.f);
|
||||
*m_alpha = 0.f;
|
||||
*m_renderOffset = Vector2D((left ? -PMONITOR->m_size.x : PMONITOR->m_size.x) * (movePerc / 100.f), 0.0);
|
||||
}
|
||||
}
|
||||
} else if (ANIMSTYLE == "fade") {
|
||||
m_renderOffset->setValueAndWarp(Vector2D(0, 0)); // fix a bug, if switching from slide -> fade.
|
||||
|
||||
if (in) {
|
||||
m_alpha->setValueAndWarp(0.f);
|
||||
*m_alpha = 1.f;
|
||||
} else {
|
||||
m_alpha->setValueAndWarp(1.f);
|
||||
*m_alpha = 0.f;
|
||||
}
|
||||
} else if (ANIMSTYLE == "slidevert") {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = m_monitor.lock();
|
||||
const auto YDISTANCE = PMONITOR->m_size.y + *PWORKSPACEGAP;
|
||||
|
||||
m_alpha->setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
|
||||
if (in) {
|
||||
m_renderOffset->setValueAndWarp(Vector2D(0.0, left ? YDISTANCE : -YDISTANCE));
|
||||
*m_renderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
*m_renderOffset = Vector2D(0.0, left ? -YDISTANCE : YDISTANCE);
|
||||
}
|
||||
} else {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = m_monitor.lock();
|
||||
const auto XDISTANCE = PMONITOR->m_size.x + *PWORKSPACEGAP;
|
||||
|
||||
m_alpha->setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
|
||||
if (in) {
|
||||
m_renderOffset->setValueAndWarp(Vector2D(left ? XDISTANCE : -XDISTANCE, 0.0));
|
||||
*m_renderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
*m_renderOffset = Vector2D(left ? -XDISTANCE : XDISTANCE, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_isSpecialWorkspace) {
|
||||
// required for open/close animations
|
||||
if (in) {
|
||||
m_alpha->setValueAndWarp(0.f);
|
||||
*m_alpha = 1.f;
|
||||
} else {
|
||||
m_alpha->setValueAndWarp(1.f);
|
||||
*m_alpha = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
if (instant) {
|
||||
m_renderOffset->warp();
|
||||
m_alpha->warp();
|
||||
}
|
||||
}
|
||||
|
||||
PHLWINDOW CWorkspace::getLastFocusedWindow() {
|
||||
if (!validMapped(m_lastFocusedWindow) || m_lastFocusedWindow->workspaceID() != m_id)
|
||||
return nullptr;
|
||||
|
||||
@ -60,7 +60,6 @@ class CWorkspace {
|
||||
|
||||
// Inert: destroyed and invalid. If this is true, release the ptr you have.
|
||||
bool inert();
|
||||
void startAnim(bool in, bool left, bool instant = false);
|
||||
MONITORID monitorID();
|
||||
PHLWINDOW getLastFocusedWindow();
|
||||
void rememberPrevWorkspace(const PHLWORKSPACE& prevWorkspace);
|
||||
|
||||
@ -15,12 +15,13 @@
|
||||
#include "../protocols/ToplevelExport.hpp"
|
||||
#include "../protocols/types/ContentType.hpp"
|
||||
#include "../xwayland/XSurface.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/animation/AnimationManager.hpp"
|
||||
#include "managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "managers/PointerManager.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
|
||||
#include <hyprutils/string/String.hpp>
|
||||
using namespace Hyprutils::String;
|
||||
@ -688,9 +689,7 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(PWINDOW);
|
||||
|
||||
// do animations
|
||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, false);
|
||||
PWINDOW->m_alpha->setValueAndWarp(0.f);
|
||||
*PWINDOW->m_alpha = 1.f;
|
||||
g_pDesktopAnimationManager->startAnimation(PWINDOW, CDesktopAnimationManager::ANIMATION_TYPE_IN);
|
||||
|
||||
PWINDOW->m_realPosition->setCallbackOnEnd(setVector2DAnimToMove);
|
||||
PWINDOW->m_realSize->setCallbackOnEnd(setVector2DAnimToMove);
|
||||
@ -838,11 +837,10 @@ void Events::listener_unmapWindow(void* owner, void* data) {
|
||||
g_pCompositor->addToFadingOutSafe(PWINDOW);
|
||||
|
||||
if (!PWINDOW->m_X11DoesntWantBorders) // don't animate out if they weren't animated in.
|
||||
*PWINDOW->m_realPosition = PWINDOW->m_realPosition->value() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise onWindowPostCreateClose will ignore it
|
||||
*PWINDOW->m_realPosition = PWINDOW->m_realPosition->value() + Vector2D(0.01f, 0.01f); // it has to be animated, otherwise CesktopAnimationManager will ignore it
|
||||
|
||||
// anims
|
||||
g_pAnimationManager->onWindowPostCreateClose(PWINDOW, true);
|
||||
*PWINDOW->m_alpha = 0.f;
|
||||
g_pDesktopAnimationManager->startAnimation(PWINDOW, CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
|
||||
// recheck idle inhibitors
|
||||
g_pInputManager->recheckIdleInhibitorStatus();
|
||||
|
||||
@ -22,7 +22,8 @@
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "sync/SyncTimeline.hpp"
|
||||
#include "time/Time.hpp"
|
||||
@ -271,7 +272,7 @@ void CMonitor::onConnect(bool noRule) {
|
||||
|
||||
if (ws->m_lastMonitor == m_name || g_pCompositor->m_monitors.size() == 1 /* avoid lost workspaces on recover */) {
|
||||
g_pCompositor->moveWorkspaceToMonitor(ws, m_self.lock());
|
||||
ws->startAnim(true, true, true);
|
||||
g_pDesktopAnimationManager->startAnimation(ws, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
|
||||
ws->m_lastMonitor = "";
|
||||
}
|
||||
}
|
||||
@ -422,7 +423,7 @@ void CMonitor::onDisconnect(bool destroy) {
|
||||
for (auto const& w : wspToMove) {
|
||||
w->m_lastMonitor = m_name;
|
||||
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
||||
w->startAnim(true, true, true);
|
||||
g_pDesktopAnimationManager->startAnimation(w, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
|
||||
}
|
||||
} else {
|
||||
g_pCompositor->m_lastFocus.reset();
|
||||
@ -1058,7 +1059,7 @@ void CMonitor::setupDefaultWS(const SMonitorRule& monitorRule) {
|
||||
g_pCompositor->moveWorkspaceToMonitor(PNEWWORKSPACE, m_self.lock());
|
||||
m_activeWorkspace = PNEWWORKSPACE;
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateMonitor(m_id);
|
||||
PNEWWORKSPACE->startAnim(true, true, true);
|
||||
g_pDesktopAnimationManager->startAnimation(PNEWWORKSPACE, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
|
||||
} else {
|
||||
if (newDefaultWorkspaceName.empty())
|
||||
newDefaultWorkspaceName = std::to_string(wsID);
|
||||
@ -1145,7 +1146,7 @@ void CMonitor::setMirror(const std::string& mirrorOf) {
|
||||
|
||||
for (auto const& w : wspToMove) {
|
||||
g_pCompositor->moveWorkspaceToMonitor(w, BACKUPMON);
|
||||
w->startAnim(true, true, true);
|
||||
g_pDesktopAnimationManager->startAnimation(w, CDesktopAnimationManager::ANIMATION_TYPE_IN, true, true);
|
||||
}
|
||||
|
||||
m_activeWorkspace.reset();
|
||||
@ -1235,8 +1236,8 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
|
||||
if (!internal) {
|
||||
const auto ANIMTOLEFT = POLDWORKSPACE && (shouldWraparound(pWorkspace->m_id, POLDWORKSPACE->m_id) ^ (pWorkspace->m_id > POLDWORKSPACE->m_id));
|
||||
if (POLDWORKSPACE)
|
||||
POLDWORKSPACE->startAnim(false, ANIMTOLEFT);
|
||||
pWorkspace->startAnim(true, ANIMTOLEFT);
|
||||
g_pDesktopAnimationManager->startAnimation(POLDWORKSPACE, CDesktopAnimationManager::ANIMATION_TYPE_OUT, ANIMTOLEFT);
|
||||
g_pDesktopAnimationManager->startAnimation(pWorkspace, CDesktopAnimationManager::ANIMATION_TYPE_IN, ANIMTOLEFT);
|
||||
|
||||
// move pinned windows
|
||||
for (auto const& w : g_pCompositor->m_windows) {
|
||||
@ -1277,14 +1278,16 @@ void CMonitor::changeWorkspace(const PHLWORKSPACE& pWorkspace, bool internal, bo
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_self.lock());
|
||||
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(pWorkspace);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
pWorkspace, pWorkspace->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
|
||||
g_pConfigManager->ensureVRR(m_self.lock());
|
||||
|
||||
g_pCompositor->updateSuspendedStates();
|
||||
|
||||
if (m_activeSpecialWorkspace)
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(m_activeSpecialWorkspace);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
m_activeSpecialWorkspace, m_activeSpecialWorkspace->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
}
|
||||
|
||||
void CMonitor::changeWorkspace(const WORKSPACEID& id, bool internal, bool noMouseMove, bool noFocus) {
|
||||
@ -1306,7 +1309,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
// remove special if exists
|
||||
if (m_activeSpecialWorkspace) {
|
||||
m_activeSpecialWorkspace->m_visible = false;
|
||||
m_activeSpecialWorkspace->startAnim(false, false);
|
||||
g_pDesktopAnimationManager->startAnimation(m_activeSpecialWorkspace, CDesktopAnimationManager::ANIMATION_TYPE_OUT, false);
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activespecial", "," + m_name});
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activespecialv2", ",," + m_name});
|
||||
}
|
||||
@ -1324,7 +1327,8 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
g_pInputManager->refocus();
|
||||
}
|
||||
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(m_activeWorkspace);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
m_activeWorkspace, m_activeWorkspace->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
|
||||
g_pConfigManager->ensureVRR(m_self.lock());
|
||||
|
||||
@ -1335,7 +1339,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
|
||||
if (m_activeSpecialWorkspace) {
|
||||
m_activeSpecialWorkspace->m_visible = false;
|
||||
m_activeSpecialWorkspace->startAnim(false, false);
|
||||
g_pDesktopAnimationManager->startAnimation(m_activeSpecialWorkspace, CDesktopAnimationManager::ANIMATION_TYPE_OUT, false);
|
||||
}
|
||||
|
||||
bool wasActive = false;
|
||||
@ -1348,7 +1352,9 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
g_pEventManager->postEvent(SHyprIPCEvent{"activespecialv2", ",," + PMWSOWNER->m_name});
|
||||
|
||||
const auto PACTIVEWORKSPACE = PMWSOWNER->m_activeWorkspace;
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(PACTIVEWORKSPACE);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(PACTIVEWORKSPACE,
|
||||
PACTIVEWORKSPACE && PACTIVEWORKSPACE->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN :
|
||||
CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
|
||||
wasActive = true;
|
||||
}
|
||||
@ -1368,7 +1374,7 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
pWorkspace->m_events.activeChanged.emit();
|
||||
|
||||
if (!wasActive)
|
||||
pWorkspace->startAnim(true, true);
|
||||
g_pDesktopAnimationManager->startAnimation(pWorkspace, CDesktopAnimationManager::ANIMATION_TYPE_IN, true);
|
||||
|
||||
for (auto const& w : g_pCompositor->m_windows) {
|
||||
if (w->m_workspace == pWorkspace) {
|
||||
@ -1408,7 +1414,8 @@ void CMonitor::setSpecialWorkspace(const PHLWORKSPACE& pWorkspace) {
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_self.lock());
|
||||
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(pWorkspace);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
pWorkspace, pWorkspace->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
|
||||
g_pConfigManager->ensureVRR(m_self.lock());
|
||||
|
||||
|
||||
@ -16,19 +16,6 @@ class CWLSurfaceResource;
|
||||
|
||||
AQUAMARINE_FORWARD(ISwitch);
|
||||
|
||||
struct SSwipeGesture {
|
||||
PHLWORKSPACE pWorkspaceBegin = nullptr;
|
||||
|
||||
double delta = 0;
|
||||
|
||||
int initialDirection = 0;
|
||||
float avgSpeed = 0;
|
||||
int speedPoints = 0;
|
||||
int touch_id = 0;
|
||||
|
||||
PHLMONITORREF pMonitor;
|
||||
};
|
||||
|
||||
struct SSwitchDevice {
|
||||
WP<Aquamarine::ISwitch> pDevice;
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../render/pass/TexPassElement.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
|
||||
|
||||
@ -166,7 +166,7 @@ void IHyprLayout::onWindowCreatedFloating(PHLWINDOW pWindow) {
|
||||
// otherwise middle of parent if available
|
||||
if (!pWindow->m_isX11) {
|
||||
if (const auto PARENT = pWindow->parent(); PARENT) {
|
||||
*pWindow->m_realPosition = PARENT->m_realPosition->goal() + PARENT->m_realSize->goal() / 2.F - desiredGeometry.size() / 2.F;
|
||||
*pWindow->m_realPosition = PARENT->m_position + PARENT->m_size / 2.F - desiredGeometry.size() / 2.F;
|
||||
pWindow->m_workspace = PARENT->m_workspace;
|
||||
pWindow->m_monitor = PARENT->m_monitor;
|
||||
centeredOnParent = true;
|
||||
|
||||
@ -26,6 +26,14 @@ enum eRectCorner : uint8_t {
|
||||
CORNER_BOTTOMLEFT = (1 << 3),
|
||||
};
|
||||
|
||||
inline eRectCorner cornerFromBox(const CBox& box, const Vector2D& pos) {
|
||||
const auto CENTER = box.middle();
|
||||
|
||||
if (pos.x < CENTER.x)
|
||||
return pos.y < CENTER.y ? CORNER_TOPLEFT : CORNER_BOTTOMLEFT;
|
||||
return pos.y < CENTER.y ? CORNER_TOPRIGHT : CORNER_BOTTOMRIGHT;
|
||||
}
|
||||
|
||||
enum eSnapEdge : uint8_t {
|
||||
SNAP_INVALID = 0,
|
||||
SNAP_UP = (1 << 0),
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "debug/Log.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../managers/EventManager.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
@ -2327,7 +2328,8 @@ SDispatchResult CKeybindManager::focusWindow(std::string regexp) {
|
||||
// don't make floating implicitly fs
|
||||
if (!PWINDOW->m_createdOverFullscreen) {
|
||||
g_pCompositor->changeWindowZOrder(PWINDOW, true);
|
||||
g_pCompositor->updateFullscreenFadeOnWorkspace(PWORKSPACE);
|
||||
g_pDesktopAnimationManager->setFullscreenFadeAnimation(
|
||||
PWORKSPACE, PWORKSPACE->m_hasFullscreenWindow ? CDesktopAnimationManager::ANIMATION_TYPE_IN : CDesktopAnimationManager::ANIMATION_TYPE_OUT);
|
||||
}
|
||||
|
||||
g_pCompositor->focusWindow(PWINDOW);
|
||||
|
||||
@ -902,7 +902,7 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
if (!g_pCompositor->m_dpmsStateOn && *PMOUSEDPMS)
|
||||
g_pKeybindManager->dpms("on");
|
||||
CKeybindManager::dpms("on");
|
||||
});
|
||||
|
||||
listener->motionAbsolute = pointer->m_pointerEvents.motionAbsolute.listen([](const IPointer::SMotionAbsoluteEvent& event) {
|
||||
@ -911,7 +911,7 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
if (!g_pCompositor->m_dpmsStateOn && *PMOUSEDPMS)
|
||||
g_pKeybindManager->dpms("on");
|
||||
CKeybindManager::dpms("on");
|
||||
});
|
||||
|
||||
listener->button = pointer->m_pointerEvents.button.listen([](const IPointer::SButtonEvent& event) {
|
||||
@ -941,7 +941,7 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
if (!g_pCompositor->m_dpmsStateOn && *PMOUSEDPMS)
|
||||
g_pKeybindManager->dpms("on");
|
||||
CKeybindManager::dpms("on");
|
||||
});
|
||||
|
||||
listener->swipeEnd = pointer->m_pointerEvents.swipeEnd.listen([](const IPointer::SSwipeEndEvent& event) {
|
||||
@ -955,21 +955,23 @@ void CPointerManager::attachPointer(SP<IPointer> pointer) {
|
||||
});
|
||||
|
||||
listener->pinchBegin = pointer->m_pointerEvents.pinchBegin.listen([](const IPointer::SPinchBeginEvent& event) {
|
||||
PROTO::pointerGestures->pinchBegin(event.timeMs, event.fingers);
|
||||
g_pInputManager->onPinchBegin(event);
|
||||
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
if (!g_pCompositor->m_dpmsStateOn && *PMOUSEDPMS)
|
||||
g_pKeybindManager->dpms("on");
|
||||
CKeybindManager::dpms("on");
|
||||
});
|
||||
|
||||
listener->pinchEnd = pointer->m_pointerEvents.pinchEnd.listen([](const IPointer::SPinchEndEvent& event) {
|
||||
PROTO::pointerGestures->pinchEnd(event.timeMs, event.cancelled);
|
||||
g_pInputManager->onPinchEnd(event);
|
||||
|
||||
PROTO::idle->onActivity();
|
||||
});
|
||||
|
||||
listener->pinchUpdate = pointer->m_pointerEvents.pinchUpdate.listen([](const IPointer::SPinchUpdateEvent& event) {
|
||||
PROTO::pointerGestures->pinchUpdate(event.timeMs, event.delta, event.scale, event.rotation);
|
||||
g_pInputManager->onPinchUpdate(event);
|
||||
|
||||
PROTO::idle->onActivity();
|
||||
});
|
||||
|
||||
@ -1005,7 +1007,7 @@ void CPointerManager::attachTouch(SP<ITouch> touch) {
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
if (!g_pCompositor->m_dpmsStateOn && *PMOUSEDPMS)
|
||||
g_pKeybindManager->dpms("on");
|
||||
CKeybindManager::dpms("on");
|
||||
});
|
||||
|
||||
listener->up = touch->m_touchEvents.up.listen([](const ITouch::SUpEvent& event) {
|
||||
@ -1046,7 +1048,7 @@ void CPointerManager::attachTablet(SP<CTablet> tablet) {
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
if (!g_pCompositor->m_dpmsStateOn && *PMOUSEDPMS)
|
||||
g_pKeybindManager->dpms("on");
|
||||
CKeybindManager::dpms("on");
|
||||
});
|
||||
|
||||
listener->proximity = tablet->m_tabletEvents.proximity.listen([](const CTablet::SProximityEvent& event) {
|
||||
@ -1060,7 +1062,7 @@ void CPointerManager::attachTablet(SP<CTablet> tablet) {
|
||||
PROTO::idle->onActivity();
|
||||
|
||||
if (!g_pCompositor->m_dpmsStateOn && *PMOUSEDPMS)
|
||||
g_pKeybindManager->dpms("on");
|
||||
CKeybindManager::dpms("on");
|
||||
});
|
||||
|
||||
listener->button = tablet->m_tabletEvents.button.listen([](const CTablet::SButtonEvent& event) {
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
#include "AnimationManager.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "HookSystemManager.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "../macros.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
#include "eventLoop/EventLoopManager.hpp"
|
||||
#include "../helpers/varlist/VarList.hpp"
|
||||
#include "../render/Renderer.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../HookSystemManager.hpp"
|
||||
#include "../../config/ConfigManager.hpp"
|
||||
#include "../../desktop/DesktopTypes.hpp"
|
||||
#include "../../helpers/AnimatedVariable.hpp"
|
||||
#include "../../macros.hpp"
|
||||
#include "../../config/ConfigValue.hpp"
|
||||
#include "../../desktop/Window.hpp"
|
||||
#include "../../desktop/LayerSurface.hpp"
|
||||
#include "../eventLoop/EventLoopManager.hpp"
|
||||
#include "../../helpers/varlist/VarList.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
|
||||
#include <hyprgraphics/color/Color.hpp>
|
||||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
@ -275,173 +275,6 @@ void CHyprAnimationManager::onTicked() {
|
||||
m_tickScheduled = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Anims
|
||||
//
|
||||
//
|
||||
|
||||
void CHyprAnimationManager::animationPopin(PHLWINDOW pWindow, bool close, float minPerc) {
|
||||
const auto GOALPOS = pWindow->m_realPosition->goal();
|
||||
const auto GOALSIZE = pWindow->m_realSize->goal();
|
||||
|
||||
if (!close) {
|
||||
pWindow->m_realSize->setValue((GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y}));
|
||||
pWindow->m_realPosition->setValue(GOALPOS + GOALSIZE / 2.f - pWindow->m_realSize->value() / 2.f);
|
||||
} else {
|
||||
*pWindow->m_realSize = (GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y});
|
||||
*pWindow->m_realPosition = GOALPOS + GOALSIZE / 2.f - pWindow->m_realSize->goal() / 2.f;
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, bool close) {
|
||||
pWindow->m_realSize->warp(false); // size we preserve in slide
|
||||
|
||||
const auto GOALPOS = pWindow->m_realPosition->goal();
|
||||
const auto GOALSIZE = pWindow->m_realSize->goal();
|
||||
|
||||
const auto PMONITOR = pWindow->m_monitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return; // unsafe state most likely
|
||||
|
||||
Vector2D posOffset;
|
||||
|
||||
if (!force.empty()) {
|
||||
if (force == "bottom")
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->m_position.y + PMONITOR->m_size.y);
|
||||
else if (force == "left")
|
||||
posOffset = GOALPOS - Vector2D(GOALSIZE.x, 0.0);
|
||||
else if (force == "right")
|
||||
posOffset = GOALPOS + Vector2D(GOALSIZE.x, 0.0);
|
||||
else
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->m_position.y - GOALSIZE.y);
|
||||
|
||||
if (!close)
|
||||
pWindow->m_realPosition->setValue(posOffset);
|
||||
else
|
||||
*pWindow->m_realPosition = posOffset;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto MIDPOINT = GOALPOS + GOALSIZE / 2.f;
|
||||
|
||||
// check sides it touches
|
||||
const bool DISPLAYLEFT = STICKS(pWindow->m_position.x, PMONITOR->m_position.x + PMONITOR->m_reservedTopLeft.x);
|
||||
const bool DISPLAYRIGHT = STICKS(pWindow->m_position.x + pWindow->m_size.x, PMONITOR->m_position.x + PMONITOR->m_size.x - PMONITOR->m_reservedBottomRight.x);
|
||||
const bool DISPLAYTOP = STICKS(pWindow->m_position.y, PMONITOR->m_position.y + PMONITOR->m_reservedTopLeft.y);
|
||||
const bool DISPLAYBOTTOM = STICKS(pWindow->m_position.y + pWindow->m_size.y, PMONITOR->m_position.y + PMONITOR->m_size.y - PMONITOR->m_reservedBottomRight.y);
|
||||
|
||||
if (DISPLAYBOTTOM && DISPLAYTOP) {
|
||||
if (DISPLAYLEFT && DISPLAYRIGHT) {
|
||||
posOffset = GOALPOS + Vector2D(0.0, GOALSIZE.y);
|
||||
} else if (DISPLAYLEFT) {
|
||||
posOffset = GOALPOS - Vector2D(GOALSIZE.x, 0.0);
|
||||
} else {
|
||||
posOffset = GOALPOS + Vector2D(GOALSIZE.x, 0.0);
|
||||
}
|
||||
} else if (DISPLAYTOP) {
|
||||
posOffset = GOALPOS - Vector2D(0.0, GOALSIZE.y);
|
||||
} else if (DISPLAYBOTTOM) {
|
||||
posOffset = GOALPOS + Vector2D(0.0, GOALSIZE.y);
|
||||
} else {
|
||||
if (MIDPOINT.y > PMONITOR->m_position.y + PMONITOR->m_size.y / 2.f)
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->m_position.y + PMONITOR->m_size.y);
|
||||
else
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->m_position.y - GOALSIZE.y);
|
||||
}
|
||||
|
||||
if (!close)
|
||||
pWindow->m_realPosition->setValue(posOffset);
|
||||
else
|
||||
*pWindow->m_realPosition = posOffset;
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::animationGnomed(PHLWINDOW pWindow, bool close) {
|
||||
const auto GOALPOS = pWindow->m_realPosition->goal();
|
||||
const auto GOALSIZE = pWindow->m_realSize->goal();
|
||||
|
||||
if (close) {
|
||||
*pWindow->m_realPosition = GOALPOS + Vector2D{0.F, GOALSIZE.y / 2.F};
|
||||
*pWindow->m_realSize = Vector2D{GOALSIZE.x, 0.F};
|
||||
} else {
|
||||
pWindow->m_realPosition->setValueAndWarp(GOALPOS + Vector2D{0.F, GOALSIZE.y / 2.F});
|
||||
pWindow->m_realSize->setValueAndWarp(Vector2D{GOALSIZE.x, 0.F});
|
||||
*pWindow->m_realPosition = GOALPOS;
|
||||
*pWindow->m_realSize = GOALSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprAnimationManager::onWindowPostCreateClose(PHLWINDOW pWindow, bool close) {
|
||||
if (!close) {
|
||||
pWindow->m_realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn"));
|
||||
pWindow->m_realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn"));
|
||||
pWindow->m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
|
||||
} else {
|
||||
pWindow->m_realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsOut"));
|
||||
pWindow->m_realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsOut"));
|
||||
pWindow->m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut"));
|
||||
}
|
||||
|
||||
std::string ANIMSTYLE = pWindow->m_realPosition->getStyle();
|
||||
std::ranges::transform(ANIMSTYLE, ANIMSTYLE.begin(), ::tolower);
|
||||
|
||||
CVarList animList(ANIMSTYLE, 0, 's');
|
||||
|
||||
// if the window is not being animated, that means the layout set a fixed size for it, don't animate.
|
||||
if (!pWindow->m_realPosition->isBeingAnimated() && !pWindow->m_realSize->isBeingAnimated())
|
||||
return;
|
||||
|
||||
// if the animation is disabled and we are leaving, ignore the anim to prevent the snapshot being fucked
|
||||
if (!pWindow->m_realPosition->enabled())
|
||||
return;
|
||||
|
||||
if (pWindow->m_windowData.animationStyle.hasValue()) {
|
||||
const auto STYLE = pWindow->m_windowData.animationStyle.value();
|
||||
// the window has config'd special anim
|
||||
if (STYLE.starts_with("slide")) {
|
||||
CVarList animList2(STYLE, 0, 's');
|
||||
animationSlide(pWindow, animList2[1], close);
|
||||
} else if (STYLE == "gnomed" || STYLE == "gnome")
|
||||
animationGnomed(pWindow, close);
|
||||
else {
|
||||
// anim popin, fallback
|
||||
|
||||
float minPerc = 0.f;
|
||||
if (STYLE.find("%") != std::string::npos) {
|
||||
try {
|
||||
auto percstr = STYLE.substr(STYLE.find_last_of(' '));
|
||||
minPerc = std::stoi(percstr.substr(0, percstr.length() - 1));
|
||||
} catch (std::exception& e) {
|
||||
; // oops
|
||||
}
|
||||
}
|
||||
|
||||
animationPopin(pWindow, close, minPerc / 100.f);
|
||||
}
|
||||
} else {
|
||||
if (animList[0] == "slide")
|
||||
animationSlide(pWindow, animList[1], close);
|
||||
else if (animList[0] == "gnomed" || animList[0] == "gnome")
|
||||
animationGnomed(pWindow, close);
|
||||
else {
|
||||
// anim popin, fallback
|
||||
|
||||
float minPerc = 0.f;
|
||||
if (!ANIMSTYLE.starts_with("%")) {
|
||||
try {
|
||||
auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' '));
|
||||
minPerc = std::stoi(percstr.substr(0, percstr.length() - 1));
|
||||
} catch (std::exception& e) {
|
||||
; // oops
|
||||
}
|
||||
}
|
||||
|
||||
animationPopin(pWindow, close, minPerc / 100.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string CHyprAnimationManager::styleValidInConfigVar(const std::string& config, const std::string& style) {
|
||||
if (config.starts_with("window")) {
|
||||
if (style.starts_with("slide") || style == "gnome" || style == "gnomed")
|
||||
@ -3,10 +3,10 @@
|
||||
#include <hyprutils/animation/AnimationManager.hpp>
|
||||
#include <hyprutils/animation/AnimatedVariable.hpp>
|
||||
|
||||
#include "../defines.hpp"
|
||||
#include "../helpers/AnimatedVariable.hpp"
|
||||
#include "../desktop/DesktopTypes.hpp"
|
||||
#include "eventLoop/EventLoopTimer.hpp"
|
||||
#include "../../defines.hpp"
|
||||
#include "../../helpers/AnimatedVariable.hpp"
|
||||
#include "../../desktop/DesktopTypes.hpp"
|
||||
#include "../eventLoop/EventLoopTimer.hpp"
|
||||
|
||||
class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||
public:
|
||||
@ -45,8 +45,6 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||
pav->m_Context.pLayer = pLayer;
|
||||
}
|
||||
|
||||
void onWindowPostCreateClose(PHLWINDOW, bool close = false);
|
||||
|
||||
std::string styleValidInConfigVar(const std::string&, const std::string&);
|
||||
|
||||
SP<CEventLoopTimer> m_animationTimer;
|
||||
@ -55,11 +53,6 @@ class CHyprAnimationManager : public Hyprutils::Animation::CAnimationManager {
|
||||
|
||||
private:
|
||||
bool m_tickScheduled = false;
|
||||
|
||||
// Anim stuff
|
||||
void animationPopin(PHLWINDOW, bool close = false, float minPerc = 0.f);
|
||||
void animationSlide(PHLWINDOW, std::string force = "", bool close = false);
|
||||
void animationGnomed(PHLWINDOW, bool close = false);
|
||||
};
|
||||
|
||||
inline UP<CHyprAnimationManager> g_pAnimationManager;
|
||||
491
src/managers/animation/DesktopAnimationManager.cpp
Normal file
491
src/managers/animation/DesktopAnimationManager.cpp
Normal file
@ -0,0 +1,491 @@
|
||||
#include "DesktopAnimationManager.hpp"
|
||||
|
||||
#include "../../desktop/LayerSurface.hpp"
|
||||
#include "../../desktop/Window.hpp"
|
||||
#include "../../desktop/Workspace.hpp"
|
||||
|
||||
#include "../../config/ConfigManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "wlr-layer-shell-unstable-v1.hpp"
|
||||
|
||||
void CDesktopAnimationManager::startAnimation(PHLWINDOW pWindow, eAnimationType type, bool force) {
|
||||
const bool CLOSE = type == ANIMATION_TYPE_OUT;
|
||||
|
||||
if (CLOSE)
|
||||
*pWindow->m_alpha = 0.F;
|
||||
else {
|
||||
pWindow->m_alpha->setValueAndWarp(0.F);
|
||||
*pWindow->m_alpha = 1.F;
|
||||
}
|
||||
|
||||
if (!CLOSE) {
|
||||
pWindow->m_realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn"));
|
||||
pWindow->m_realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsIn"));
|
||||
pWindow->m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeIn"));
|
||||
} else {
|
||||
pWindow->m_realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsOut"));
|
||||
pWindow->m_realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("windowsOut"));
|
||||
pWindow->m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeOut"));
|
||||
}
|
||||
|
||||
std::string ANIMSTYLE = pWindow->m_realPosition->getStyle();
|
||||
std::ranges::transform(ANIMSTYLE, ANIMSTYLE.begin(), ::tolower);
|
||||
|
||||
CVarList animList(ANIMSTYLE, 0, 's');
|
||||
|
||||
// if the window is not being animated, that means the layout set a fixed size for it, don't animate.
|
||||
if (!pWindow->m_realPosition->isBeingAnimated() && !pWindow->m_realSize->isBeingAnimated() && !force)
|
||||
return;
|
||||
|
||||
// if the animation is disabled and we are leaving, ignore the anim to prevent the snapshot being fucked
|
||||
if (!pWindow->m_realPosition->enabled() && !force)
|
||||
return;
|
||||
|
||||
if (pWindow->m_windowData.animationStyle.hasValue()) {
|
||||
const auto STYLE = pWindow->m_windowData.animationStyle.value();
|
||||
// the window has config'd special anim
|
||||
if (STYLE.starts_with("slide")) {
|
||||
CVarList animList2(STYLE, 0, 's');
|
||||
animationSlide(pWindow, animList2[1], CLOSE);
|
||||
} else if (STYLE == "gnomed" || STYLE == "gnome")
|
||||
animationGnomed(pWindow, CLOSE);
|
||||
else {
|
||||
// anim popin, fallback
|
||||
|
||||
float minPerc = 0.f;
|
||||
if (STYLE.find("%") != std::string::npos) {
|
||||
try {
|
||||
auto percstr = STYLE.substr(STYLE.find_last_of(' '));
|
||||
minPerc = std::stoi(percstr.substr(0, percstr.length() - 1));
|
||||
} catch (std::exception& e) {
|
||||
; // oops
|
||||
}
|
||||
}
|
||||
|
||||
animationPopin(pWindow, CLOSE, minPerc / 100.f);
|
||||
}
|
||||
} else {
|
||||
if (animList[0] == "slide")
|
||||
animationSlide(pWindow, animList[1], CLOSE);
|
||||
else if (animList[0] == "gnomed" || animList[0] == "gnome")
|
||||
animationGnomed(pWindow, CLOSE);
|
||||
else {
|
||||
// anim popin, fallback
|
||||
|
||||
float minPerc = 0.f;
|
||||
if (!ANIMSTYLE.starts_with("%")) {
|
||||
try {
|
||||
auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' '));
|
||||
minPerc = std::stoi(percstr.substr(0, percstr.length() - 1));
|
||||
} catch (std::exception& e) {
|
||||
; // oops
|
||||
}
|
||||
}
|
||||
|
||||
animationPopin(pWindow, CLOSE, minPerc / 100.f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDesktopAnimationManager::startAnimation(PHLLS ls, eAnimationType type, bool instant) {
|
||||
const bool IN = type == ANIMATION_TYPE_IN;
|
||||
|
||||
if (IN) {
|
||||
ls->m_alpha->setValueAndWarp(0.F);
|
||||
*ls->m_alpha = 1.F;
|
||||
} else
|
||||
*ls->m_alpha = 0.F;
|
||||
|
||||
if (IN) {
|
||||
ls->m_realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
||||
ls->m_realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersIn"));
|
||||
ls->m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersIn"));
|
||||
} else {
|
||||
ls->m_realPosition->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
||||
ls->m_realSize->setConfig(g_pConfigManager->getAnimationPropertyConfig("layersOut"));
|
||||
ls->m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig("fadeLayersOut"));
|
||||
}
|
||||
|
||||
const auto ANIMSTYLE = ls->m_animationStyle.value_or(ls->m_realPosition->getStyle());
|
||||
if (ANIMSTYLE.starts_with("slide")) {
|
||||
// get closest edge
|
||||
const auto MIDDLE = ls->m_geometry.middle();
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromVector(MIDDLE);
|
||||
|
||||
if (!PMONITOR) { // can rarely happen on exit
|
||||
ls->m_alpha->setValueAndWarp(IN ? 1.F : 0.F);
|
||||
return;
|
||||
}
|
||||
|
||||
int force = -1;
|
||||
|
||||
CVarList args(ANIMSTYLE, 0, 's');
|
||||
if (args.size() > 1) {
|
||||
const auto ARG2 = args[1];
|
||||
if (ARG2 == "top")
|
||||
force = 0;
|
||||
else if (ARG2 == "bottom")
|
||||
force = 1;
|
||||
else if (ARG2 == "left")
|
||||
force = 2;
|
||||
else if (ARG2 == "right")
|
||||
force = 3;
|
||||
}
|
||||
|
||||
const std::array<Vector2D, 4> edgePoints = {
|
||||
PMONITOR->m_position + Vector2D{PMONITOR->m_size.x / 2, 0.0},
|
||||
PMONITOR->m_position + Vector2D{PMONITOR->m_size.x / 2, PMONITOR->m_size.y},
|
||||
PMONITOR->m_position + Vector2D{0.0, PMONITOR->m_size.y},
|
||||
PMONITOR->m_position + Vector2D{PMONITOR->m_size.x, PMONITOR->m_size.y / 2},
|
||||
};
|
||||
|
||||
float closest = std::numeric_limits<float>::max();
|
||||
int leader = force;
|
||||
if (leader == -1) {
|
||||
for (size_t i = 0; i < 4; ++i) {
|
||||
float dist = MIDDLE.distance(edgePoints[i]);
|
||||
if (dist < closest) {
|
||||
leader = i;
|
||||
closest = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ls->m_realSize->setValueAndWarp(ls->m_geometry.size());
|
||||
|
||||
Vector2D prePos;
|
||||
|
||||
switch (leader) {
|
||||
case 0:
|
||||
// TOP
|
||||
prePos = {ls->m_geometry.x, PMONITOR->m_position.y - ls->m_geometry.h};
|
||||
break;
|
||||
case 1:
|
||||
// BOTTOM
|
||||
prePos = {ls->m_geometry.x, PMONITOR->m_position.y + PMONITOR->m_size.y};
|
||||
break;
|
||||
case 2:
|
||||
// LEFT
|
||||
prePos = {PMONITOR->m_position.x - ls->m_geometry.w, ls->m_geometry.y};
|
||||
break;
|
||||
case 3:
|
||||
// RIGHT
|
||||
prePos = {PMONITOR->m_position.x + PMONITOR->m_size.x, ls->m_geometry.y};
|
||||
break;
|
||||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
if (IN) {
|
||||
ls->m_realPosition->setValueAndWarp(prePos);
|
||||
*ls->m_realPosition = ls->m_geometry.pos();
|
||||
} else {
|
||||
ls->m_realPosition->setValueAndWarp(ls->m_geometry.pos());
|
||||
*ls->m_realPosition = prePos;
|
||||
}
|
||||
|
||||
} else if (ANIMSTYLE.starts_with("popin")) {
|
||||
float minPerc = 0.f;
|
||||
if (ANIMSTYLE.find("%") != std::string::npos) {
|
||||
try {
|
||||
auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' '));
|
||||
minPerc = std::stoi(percstr.substr(0, percstr.length() - 1));
|
||||
} catch (std::exception& e) {
|
||||
; // oops
|
||||
}
|
||||
}
|
||||
|
||||
minPerc *= 0.01;
|
||||
|
||||
const auto GOALSIZE = (ls->m_geometry.size() * minPerc).clamp({5, 5});
|
||||
const auto GOALPOS = ls->m_geometry.pos() + (ls->m_geometry.size() - GOALSIZE) / 2.f;
|
||||
|
||||
ls->m_alpha->setValueAndWarp(IN ? 0.f : 1.f);
|
||||
*ls->m_alpha = IN ? 1.f : 0.f;
|
||||
|
||||
if (IN) {
|
||||
ls->m_realSize->setValueAndWarp(GOALSIZE);
|
||||
ls->m_realPosition->setValueAndWarp(GOALPOS);
|
||||
*ls->m_realSize = ls->m_geometry.size();
|
||||
*ls->m_realPosition = ls->m_geometry.pos();
|
||||
} else {
|
||||
ls->m_realSize->setValueAndWarp(ls->m_geometry.size());
|
||||
ls->m_realPosition->setValueAndWarp(ls->m_geometry.pos());
|
||||
*ls->m_realSize = GOALSIZE;
|
||||
*ls->m_realPosition = GOALPOS;
|
||||
}
|
||||
} else {
|
||||
// fade
|
||||
ls->m_realPosition->setValueAndWarp(ls->m_geometry.pos());
|
||||
ls->m_realSize->setValueAndWarp(ls->m_geometry.size());
|
||||
*ls->m_alpha = IN ? 1.f : 0.f;
|
||||
}
|
||||
|
||||
if (instant) {
|
||||
ls->m_realPosition->warp();
|
||||
ls->m_realSize->warp();
|
||||
ls->m_alpha->warp();
|
||||
}
|
||||
}
|
||||
|
||||
void CDesktopAnimationManager::startAnimation(PHLWORKSPACE ws, eAnimationType type, bool left, bool instant) {
|
||||
const bool IN = type == ANIMATION_TYPE_IN;
|
||||
|
||||
if (!instant) {
|
||||
const std::string ANIMNAME = std::format("{}{}", ws->m_isSpecialWorkspace ? "specialWorkspace" : "workspaces", IN ? "In" : "Out");
|
||||
|
||||
ws->m_alpha->setConfig(g_pConfigManager->getAnimationPropertyConfig(ANIMNAME));
|
||||
ws->m_renderOffset->setConfig(g_pConfigManager->getAnimationPropertyConfig(ANIMNAME));
|
||||
}
|
||||
|
||||
const auto ANIMSTYLE = ws->m_alpha->getStyle();
|
||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||
|
||||
// set floating windows offset callbacks
|
||||
ws->m_renderOffset->setUpdateCallback([weak = PHLWORKSPACEREF{ws}](auto) {
|
||||
if (!weak)
|
||||
return;
|
||||
|
||||
for (auto const& w : g_pCompositor->m_windows) {
|
||||
if (!validMapped(w) || w->workspaceID() != weak->m_id)
|
||||
continue;
|
||||
|
||||
w->onWorkspaceAnimUpdate();
|
||||
};
|
||||
});
|
||||
|
||||
if (ANIMSTYLE.starts_with("slidefade")) {
|
||||
const auto PMONITOR = ws->m_monitor.lock();
|
||||
float movePerc = 100.f;
|
||||
|
||||
if (ANIMSTYLE.find('%') != std::string::npos) {
|
||||
try {
|
||||
auto percstr = ANIMSTYLE.substr(ANIMSTYLE.find_last_of(' ') + 1);
|
||||
movePerc = std::stoi(percstr.substr(0, percstr.length() - 1));
|
||||
} catch (std::exception& e) { Debug::log(ERR, "Error in startAnim: invalid percentage"); }
|
||||
}
|
||||
|
||||
ws->m_alpha->setValueAndWarp(1.f);
|
||||
ws->m_renderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
|
||||
if (ANIMSTYLE.starts_with("slidefadevert")) {
|
||||
if (IN) {
|
||||
ws->m_alpha->setValueAndWarp(0.f);
|
||||
ws->m_renderOffset->setValueAndWarp(Vector2D(0.0, (left ? PMONITOR->m_size.y : -PMONITOR->m_size.y) * (movePerc / 100.f)));
|
||||
*ws->m_alpha = 1.f;
|
||||
*ws->m_renderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
ws->m_alpha->setValueAndWarp(1.f);
|
||||
*ws->m_alpha = 0.f;
|
||||
*ws->m_renderOffset = Vector2D(0.0, (left ? -PMONITOR->m_size.y : PMONITOR->m_size.y) * (movePerc / 100.f));
|
||||
}
|
||||
} else {
|
||||
if (IN) {
|
||||
ws->m_alpha->setValueAndWarp(0.f);
|
||||
ws->m_renderOffset->setValueAndWarp(Vector2D((left ? PMONITOR->m_size.x : -PMONITOR->m_size.x) * (movePerc / 100.f), 0.0));
|
||||
*ws->m_alpha = 1.f;
|
||||
*ws->m_renderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
ws->m_alpha->setValueAndWarp(1.f);
|
||||
*ws->m_alpha = 0.f;
|
||||
*ws->m_renderOffset = Vector2D((left ? -PMONITOR->m_size.x : PMONITOR->m_size.x) * (movePerc / 100.f), 0.0);
|
||||
}
|
||||
}
|
||||
} else if (ANIMSTYLE == "fade") {
|
||||
ws->m_renderOffset->setValueAndWarp(Vector2D(0, 0)); // fix a bug, if switching from slide -> fade.
|
||||
|
||||
if (IN) {
|
||||
ws->m_alpha->setValueAndWarp(0.f);
|
||||
*ws->m_alpha = 1.f;
|
||||
} else {
|
||||
ws->m_alpha->setValueAndWarp(1.f);
|
||||
*ws->m_alpha = 0.f;
|
||||
}
|
||||
} else if (ANIMSTYLE == "slidevert") {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = ws->m_monitor.lock();
|
||||
const auto YDISTANCE = PMONITOR->m_size.y + *PWORKSPACEGAP;
|
||||
|
||||
ws->m_alpha->setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
|
||||
if (IN) {
|
||||
ws->m_renderOffset->setValueAndWarp(Vector2D(0.0, left ? YDISTANCE : -YDISTANCE));
|
||||
*ws->m_renderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
*ws->m_renderOffset = Vector2D(0.0, left ? -YDISTANCE : YDISTANCE);
|
||||
}
|
||||
} else {
|
||||
// fallback is slide
|
||||
const auto PMONITOR = ws->m_monitor.lock();
|
||||
const auto XDISTANCE = PMONITOR->m_size.x + *PWORKSPACEGAP;
|
||||
|
||||
ws->m_alpha->setValueAndWarp(1.f); // fix a bug, if switching from fade -> slide.
|
||||
|
||||
if (IN) {
|
||||
ws->m_renderOffset->setValueAndWarp(Vector2D(left ? XDISTANCE : -XDISTANCE, 0.0));
|
||||
*ws->m_renderOffset = Vector2D(0, 0);
|
||||
} else {
|
||||
*ws->m_renderOffset = Vector2D(left ? -XDISTANCE : XDISTANCE, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (ws->m_isSpecialWorkspace) {
|
||||
// required for open/close animations
|
||||
if (IN) {
|
||||
ws->m_alpha->setValueAndWarp(0.f);
|
||||
*ws->m_alpha = 1.f;
|
||||
} else {
|
||||
ws->m_alpha->setValueAndWarp(1.f);
|
||||
*ws->m_alpha = 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
if (instant) {
|
||||
ws->m_renderOffset->warp();
|
||||
ws->m_alpha->warp();
|
||||
}
|
||||
}
|
||||
|
||||
void CDesktopAnimationManager::animationPopin(PHLWINDOW pWindow, bool close, float minPerc) {
|
||||
const auto GOALPOS = pWindow->m_realPosition->goal();
|
||||
const auto GOALSIZE = pWindow->m_realSize->goal();
|
||||
|
||||
if (!close) {
|
||||
pWindow->m_realSize->setValue((GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y}));
|
||||
pWindow->m_realPosition->setValue(GOALPOS + GOALSIZE / 2.f - pWindow->m_realSize->value() / 2.f);
|
||||
} else {
|
||||
*pWindow->m_realSize = (GOALSIZE * minPerc).clamp({5, 5}, {GOALSIZE.x, GOALSIZE.y});
|
||||
*pWindow->m_realPosition = GOALPOS + GOALSIZE / 2.f - pWindow->m_realSize->goal() / 2.f;
|
||||
}
|
||||
}
|
||||
|
||||
void CDesktopAnimationManager::animationSlide(PHLWINDOW pWindow, std::string force, bool close) {
|
||||
pWindow->m_realSize->warp(false); // size we preserve in slide
|
||||
|
||||
const auto GOALPOS = pWindow->m_realPosition->goal();
|
||||
const auto GOALSIZE = pWindow->m_realSize->goal();
|
||||
|
||||
const auto PMONITOR = pWindow->m_monitor.lock();
|
||||
|
||||
if (!PMONITOR)
|
||||
return; // unsafe state most likely
|
||||
|
||||
Vector2D posOffset;
|
||||
|
||||
if (!force.empty()) {
|
||||
if (force == "bottom")
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->m_position.y + PMONITOR->m_size.y);
|
||||
else if (force == "left")
|
||||
posOffset = GOALPOS - Vector2D(GOALSIZE.x, 0.0);
|
||||
else if (force == "right")
|
||||
posOffset = GOALPOS + Vector2D(GOALSIZE.x, 0.0);
|
||||
else
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->m_position.y - GOALSIZE.y);
|
||||
|
||||
if (!close)
|
||||
pWindow->m_realPosition->setValue(posOffset);
|
||||
else
|
||||
*pWindow->m_realPosition = posOffset;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const auto MIDPOINT = GOALPOS + GOALSIZE / 2.f;
|
||||
|
||||
// check sides it touches
|
||||
const bool DISPLAYLEFT = STICKS(pWindow->m_position.x, PMONITOR->m_position.x + PMONITOR->m_reservedTopLeft.x);
|
||||
const bool DISPLAYRIGHT = STICKS(pWindow->m_position.x + pWindow->m_size.x, PMONITOR->m_position.x + PMONITOR->m_size.x - PMONITOR->m_reservedBottomRight.x);
|
||||
const bool DISPLAYTOP = STICKS(pWindow->m_position.y, PMONITOR->m_position.y + PMONITOR->m_reservedTopLeft.y);
|
||||
const bool DISPLAYBOTTOM = STICKS(pWindow->m_position.y + pWindow->m_size.y, PMONITOR->m_position.y + PMONITOR->m_size.y - PMONITOR->m_reservedBottomRight.y);
|
||||
|
||||
if (DISPLAYBOTTOM && DISPLAYTOP) {
|
||||
if (DISPLAYLEFT && DISPLAYRIGHT) {
|
||||
posOffset = GOALPOS + Vector2D(0.0, GOALSIZE.y);
|
||||
} else if (DISPLAYLEFT) {
|
||||
posOffset = GOALPOS - Vector2D(GOALSIZE.x, 0.0);
|
||||
} else {
|
||||
posOffset = GOALPOS + Vector2D(GOALSIZE.x, 0.0);
|
||||
}
|
||||
} else if (DISPLAYTOP) {
|
||||
posOffset = GOALPOS - Vector2D(0.0, GOALSIZE.y);
|
||||
} else if (DISPLAYBOTTOM) {
|
||||
posOffset = GOALPOS + Vector2D(0.0, GOALSIZE.y);
|
||||
} else {
|
||||
if (MIDPOINT.y > PMONITOR->m_position.y + PMONITOR->m_size.y / 2.f)
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->m_position.y + PMONITOR->m_size.y);
|
||||
else
|
||||
posOffset = Vector2D(GOALPOS.x, PMONITOR->m_position.y - GOALSIZE.y);
|
||||
}
|
||||
|
||||
if (!close)
|
||||
pWindow->m_realPosition->setValue(posOffset);
|
||||
else
|
||||
*pWindow->m_realPosition = posOffset;
|
||||
}
|
||||
|
||||
void CDesktopAnimationManager::animationGnomed(PHLWINDOW pWindow, bool close) {
|
||||
const auto GOALPOS = pWindow->m_realPosition->goal();
|
||||
const auto GOALSIZE = pWindow->m_realSize->goal();
|
||||
|
||||
if (close) {
|
||||
*pWindow->m_realPosition = GOALPOS + Vector2D{0.F, GOALSIZE.y / 2.F};
|
||||
*pWindow->m_realSize = Vector2D{GOALSIZE.x, 0.F};
|
||||
} else {
|
||||
pWindow->m_realPosition->setValueAndWarp(GOALPOS + Vector2D{0.F, GOALSIZE.y / 2.F});
|
||||
pWindow->m_realSize->setValueAndWarp(Vector2D{GOALSIZE.x, 0.F});
|
||||
*pWindow->m_realPosition = GOALPOS;
|
||||
*pWindow->m_realSize = GOALSIZE;
|
||||
}
|
||||
}
|
||||
|
||||
void CDesktopAnimationManager::setFullscreenFadeAnimation(PHLWORKSPACE ws, eAnimationType type) {
|
||||
if (!ws)
|
||||
return;
|
||||
|
||||
const auto FULLSCREEN = type == ANIMATION_TYPE_IN;
|
||||
|
||||
for (auto const& w : g_pCompositor->m_windows) {
|
||||
if (w->m_workspace == ws) {
|
||||
|
||||
if (w->m_fadingOut || w->m_pinned || w->isFullscreen())
|
||||
continue;
|
||||
|
||||
if (!FULLSCREEN)
|
||||
*w->m_alpha = 1.F;
|
||||
else if (!w->isFullscreen())
|
||||
*w->m_alpha = !w->m_createdOverFullscreen ? 0.f : 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
const auto PMONITOR = ws->m_monitor.lock();
|
||||
|
||||
if (ws->m_id == PMONITOR->activeWorkspaceID() || ws->m_id == PMONITOR->activeSpecialWorkspaceID()) {
|
||||
for (auto const& ls : PMONITOR->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
if (!ls->m_fadingOut)
|
||||
*ls->m_alpha = FULLSCREEN && ws->m_fullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CDesktopAnimationManager::overrideFullscreenFadeAmount(PHLWORKSPACE ws, float fade, PHLWINDOW exclude) {
|
||||
for (auto const& w : g_pCompositor->m_windows) {
|
||||
if (w == exclude)
|
||||
continue;
|
||||
|
||||
if (w->m_workspace == ws) {
|
||||
if (w->m_fadingOut || w->m_pinned || w->isFullscreen())
|
||||
continue;
|
||||
|
||||
*w->m_alpha = fade;
|
||||
}
|
||||
}
|
||||
|
||||
const auto PMONITOR = ws->m_monitor.lock();
|
||||
|
||||
if (ws->m_id == PMONITOR->activeWorkspaceID() || ws->m_id == PMONITOR->activeSpecialWorkspaceID()) {
|
||||
for (auto const& ls : PMONITOR->m_layerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
|
||||
if (!ls->m_fadingOut)
|
||||
*ls->m_alpha = fade;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/managers/animation/DesktopAnimationManager.hpp
Normal file
26
src/managers/animation/DesktopAnimationManager.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../helpers/memory/Memory.hpp"
|
||||
#include "../../desktop/DesktopTypes.hpp"
|
||||
|
||||
class CDesktopAnimationManager {
|
||||
public:
|
||||
enum eAnimationType : uint8_t {
|
||||
ANIMATION_TYPE_IN = 0,
|
||||
ANIMATION_TYPE_OUT,
|
||||
};
|
||||
|
||||
void startAnimation(PHLWINDOW w, eAnimationType type, bool force = false);
|
||||
void startAnimation(PHLLS ls, eAnimationType type, bool instant = false);
|
||||
void startAnimation(PHLWORKSPACE ws, eAnimationType type, bool left = true, bool instant = false);
|
||||
|
||||
void setFullscreenFadeAnimation(PHLWORKSPACE ws, eAnimationType type);
|
||||
void overrideFullscreenFadeAmount(PHLWORKSPACE ws, float fade, PHLWINDOW exclude = nullptr);
|
||||
|
||||
private:
|
||||
void animationPopin(PHLWINDOW w, bool close = false, float minPerc = 0.f);
|
||||
void animationSlide(PHLWINDOW w, std::string force = "", bool close = false);
|
||||
void animationGnomed(PHLWINDOW w, bool close = false);
|
||||
};
|
||||
|
||||
inline UP<CDesktopAnimationManager> g_pDesktopAnimationManager = makeUnique<CDesktopAnimationManager>();
|
||||
@ -12,6 +12,7 @@
|
||||
#include "../../protocols/IdleInhibit.hpp"
|
||||
#include "../../protocols/RelativePointer.hpp"
|
||||
#include "../../protocols/PointerConstraints.hpp"
|
||||
#include "../../protocols/PointerGestures.hpp"
|
||||
#include "../../protocols/IdleNotify.hpp"
|
||||
#include "../../protocols/SessionLock.hpp"
|
||||
#include "../../protocols/InputMethodV2.hpp"
|
||||
@ -41,6 +42,8 @@
|
||||
#include "../../helpers/time/Time.hpp"
|
||||
#include "../../helpers/MiscFunctions.hpp"
|
||||
|
||||
#include "trackpad/TrackpadGestures.hpp"
|
||||
|
||||
#include <aquamarine/input/Input.hpp>
|
||||
|
||||
CInputManager::CInputManager() {
|
||||
@ -1946,3 +1949,51 @@ void CInputManager::recheckMouseWarpOnMouseInput() {
|
||||
if (!m_lastInputMouse && *PWARPFORNONMOUSE)
|
||||
g_pPointerManager->warpTo(m_lastMousePos);
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeBegin(IPointer::SSwipeBeginEvent e) {
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("swipeBegin", e);
|
||||
|
||||
g_pTrackpadGestures->gestureBegin(e);
|
||||
|
||||
PROTO::pointerGestures->swipeBegin(e.timeMs, e.fingers);
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeUpdate(IPointer::SSwipeUpdateEvent e) {
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("swipeUpdate", e);
|
||||
|
||||
g_pTrackpadGestures->gestureUpdate(e);
|
||||
|
||||
PROTO::pointerGestures->swipeUpdate(e.timeMs, e.delta);
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeEnd(IPointer::SSwipeEndEvent e) {
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("swipeEnd", e);
|
||||
|
||||
g_pTrackpadGestures->gestureEnd(e);
|
||||
|
||||
PROTO::pointerGestures->swipeEnd(e.timeMs, e.cancelled);
|
||||
}
|
||||
|
||||
void CInputManager::onPinchBegin(IPointer::SPinchBeginEvent e) {
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("pinchBegin", e);
|
||||
|
||||
g_pTrackpadGestures->gestureBegin(e);
|
||||
|
||||
PROTO::pointerGestures->pinchBegin(e.timeMs, e.fingers);
|
||||
}
|
||||
|
||||
void CInputManager::onPinchUpdate(IPointer::SPinchUpdateEvent e) {
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("pinchUpdate", e);
|
||||
|
||||
g_pTrackpadGestures->gestureUpdate(e);
|
||||
|
||||
PROTO::pointerGestures->pinchUpdate(e.timeMs, e.delta, e.scale, e.rotation);
|
||||
}
|
||||
|
||||
void CInputManager::onPinchEnd(IPointer::SPinchEndEvent e) {
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("pinchEnd", e);
|
||||
|
||||
g_pTrackpadGestures->gestureEnd(e);
|
||||
|
||||
PROTO::pointerGestures->pinchEnd(e.timeMs, e.cancelled);
|
||||
}
|
||||
|
||||
@ -141,6 +141,10 @@ class CInputManager {
|
||||
void onSwipeEnd(IPointer::SSwipeEndEvent);
|
||||
void onSwipeUpdate(IPointer::SSwipeUpdateEvent);
|
||||
|
||||
void onPinchBegin(IPointer::SPinchBeginEvent);
|
||||
void onPinchUpdate(IPointer::SPinchUpdateEvent);
|
||||
void onPinchEnd(IPointer::SPinchEndEvent);
|
||||
|
||||
void onTabletAxis(CTablet::SAxisEvent);
|
||||
void onTabletProximity(CTablet::SProximityEvent);
|
||||
void onTabletTip(CTablet::STipEvent);
|
||||
@ -179,8 +183,6 @@ class CInputManager {
|
||||
void recheckIdleInhibitorStatus();
|
||||
bool isWindowInhibiting(const PHLWINDOW& pWindow, bool onlyHl = true);
|
||||
|
||||
SSwipeGesture m_activeSwipe;
|
||||
|
||||
CTimer m_lastCursorMovement;
|
||||
|
||||
CInputMethodRelay m_relay;
|
||||
@ -276,11 +278,6 @@ class CInputManager {
|
||||
};
|
||||
std::vector<UP<SIdleInhibitor>> m_idleInhibitors;
|
||||
|
||||
// swipe
|
||||
void beginWorkspaceSwipe();
|
||||
void updateWorkspaceSwipe(double);
|
||||
void endWorkspaceSwipe();
|
||||
|
||||
void setBorderCursorIcon(eBorderIconDirection);
|
||||
void setCursorIconOnBorder(PHLWINDOW w);
|
||||
|
||||
@ -313,6 +310,7 @@ class CInputManager {
|
||||
|
||||
friend class CKeybindManager;
|
||||
friend class CWLSurface;
|
||||
friend class CWorkspaceSwipeGesture;
|
||||
};
|
||||
|
||||
inline UP<CInputManager> g_pInputManager;
|
||||
|
||||
@ -1,348 +0,0 @@
|
||||
#include "InputManager.hpp"
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../desktop/LayerSurface.hpp"
|
||||
#include "../../config/ConfigValue.hpp"
|
||||
#include "../../managers/HookSystemManager.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
|
||||
void CInputManager::onSwipeBegin(IPointer::SSwipeBeginEvent e) {
|
||||
static auto PSWIPE = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe");
|
||||
static auto PSWIPEFINGERS = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_fingers");
|
||||
static auto PSWIPEMINFINGERS = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_min_fingers");
|
||||
static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
|
||||
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("swipeBegin", e);
|
||||
|
||||
if ((!*PSWIPEMINFINGERS && e.fingers != *PSWIPEFINGERS) || (*PSWIPEMINFINGERS && e.fingers < *PSWIPEFINGERS) || *PSWIPE == 0 || g_pSessionLockManager->isSessionLocked())
|
||||
return;
|
||||
|
||||
int onMonitor = 0;
|
||||
for (auto const& w : g_pCompositor->getWorkspaces()) {
|
||||
if (w->m_monitor == g_pCompositor->m_lastMonitor && !g_pCompositor->isWorkspaceSpecial(w->m_id))
|
||||
onMonitor++;
|
||||
}
|
||||
|
||||
if (onMonitor < 2 && !*PSWIPENEW)
|
||||
return; // disallow swiping when there's 1 workspace on a monitor
|
||||
|
||||
beginWorkspaceSwipe();
|
||||
}
|
||||
|
||||
void CInputManager::beginWorkspaceSwipe() {
|
||||
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
|
||||
|
||||
Debug::log(LOG, "Starting a swipe from {}", PWORKSPACE->m_name);
|
||||
|
||||
m_activeSwipe.pWorkspaceBegin = PWORKSPACE;
|
||||
m_activeSwipe.delta = 0;
|
||||
m_activeSwipe.pMonitor = g_pCompositor->m_lastMonitor;
|
||||
m_activeSwipe.avgSpeed = 0;
|
||||
m_activeSwipe.speedPoints = 0;
|
||||
|
||||
if (PWORKSPACE->m_hasFullscreenWindow) {
|
||||
for (auto const& ls : g_pCompositor->m_lastMonitor->m_layerSurfaceLayers[2]) {
|
||||
*ls->m_alpha = 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeEnd(IPointer::SSwipeEndEvent e) {
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("swipeEnd", e);
|
||||
|
||||
if (!m_activeSwipe.pWorkspaceBegin)
|
||||
return; // no valid swipe
|
||||
endWorkspaceSwipe();
|
||||
}
|
||||
|
||||
void CInputManager::endWorkspaceSwipe() {
|
||||
static auto PSWIPEPERC = CConfigValue<Hyprlang::FLOAT>("gestures:workspace_swipe_cancel_ratio");
|
||||
static auto PSWIPEDIST = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_distance");
|
||||
static auto PSWIPEFORC = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_min_speed_to_force");
|
||||
static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
|
||||
static auto PSWIPEUSER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_use_r");
|
||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||
const auto ANIMSTYLE = m_activeSwipe.pWorkspaceBegin->m_renderOffset->getStyle();
|
||||
const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert");
|
||||
|
||||
// commit
|
||||
auto workspaceIDLeft = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r-1" : "m-1")).id;
|
||||
auto workspaceIDRight = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r+1" : "m+1")).id;
|
||||
const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, sc<int64_t>(1LL), sc<int64_t>(UINT32_MAX));
|
||||
|
||||
// If we've been swiping off the right end with PSWIPENEW enabled, there is
|
||||
// no workspace there yet, and we need to choose an ID for a new one now.
|
||||
if (workspaceIDRight <= m_activeSwipe.pWorkspaceBegin->m_id && *PSWIPENEW) {
|
||||
workspaceIDRight = getWorkspaceIDNameFromString("r+1").id;
|
||||
}
|
||||
|
||||
auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW || PSWIPENUMBER
|
||||
auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); // not guaranteed if PSWIPENUMBER
|
||||
|
||||
const auto RENDEROFFSETMIDDLE = m_activeSwipe.pWorkspaceBegin->m_renderOffset->value();
|
||||
const auto XDISTANCE = m_activeSwipe.pMonitor->m_size.x + *PWORKSPACEGAP;
|
||||
const auto YDISTANCE = m_activeSwipe.pMonitor->m_size.y + *PWORKSPACEGAP;
|
||||
|
||||
PHLWORKSPACE pSwitchedTo = nullptr;
|
||||
|
||||
if ((abs(m_activeSwipe.delta) < SWIPEDISTANCE * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_activeSwipe.avgSpeed < *PSWIPEFORC))) ||
|
||||
abs(m_activeSwipe.delta) < 2) {
|
||||
// revert
|
||||
if (abs(m_activeSwipe.delta) < 2) {
|
||||
if (PWORKSPACEL)
|
||||
PWORKSPACEL->m_renderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
if (PWORKSPACER)
|
||||
PWORKSPACER->m_renderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
} else {
|
||||
if (m_activeSwipe.delta < 0) {
|
||||
// to left
|
||||
|
||||
if (PWORKSPACEL) {
|
||||
if (VERTANIMS)
|
||||
*PWORKSPACEL->m_renderOffset = Vector2D{0.0, -YDISTANCE};
|
||||
else
|
||||
*PWORKSPACEL->m_renderOffset = Vector2D{-XDISTANCE, 0.0};
|
||||
}
|
||||
} else if (PWORKSPACER) {
|
||||
// to right
|
||||
if (VERTANIMS)
|
||||
*PWORKSPACER->m_renderOffset = Vector2D{0.0, YDISTANCE};
|
||||
else
|
||||
*PWORKSPACER->m_renderOffset = Vector2D{XDISTANCE, 0.0};
|
||||
}
|
||||
|
||||
*m_activeSwipe.pWorkspaceBegin->m_renderOffset = Vector2D();
|
||||
}
|
||||
|
||||
pSwitchedTo = m_activeSwipe.pWorkspaceBegin;
|
||||
} else if (m_activeSwipe.delta < 0) {
|
||||
// switch to left
|
||||
const auto RENDEROFFSET = PWORKSPACEL ? PWORKSPACEL->m_renderOffset->value() : Vector2D();
|
||||
|
||||
if (PWORKSPACEL)
|
||||
m_activeSwipe.pMonitor->changeWorkspace(workspaceIDLeft);
|
||||
else {
|
||||
m_activeSwipe.pMonitor->changeWorkspace(g_pCompositor->createNewWorkspace(workspaceIDLeft, m_activeSwipe.pMonitor->m_id));
|
||||
PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
PWORKSPACEL->rememberPrevWorkspace(m_activeSwipe.pWorkspaceBegin);
|
||||
}
|
||||
|
||||
PWORKSPACEL->m_renderOffset->setValue(RENDEROFFSET);
|
||||
PWORKSPACEL->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValue(RENDEROFFSETMIDDLE);
|
||||
if (VERTANIMS)
|
||||
*m_activeSwipe.pWorkspaceBegin->m_renderOffset = Vector2D(0.0, YDISTANCE);
|
||||
else
|
||||
*m_activeSwipe.pWorkspaceBegin->m_renderOffset = Vector2D(XDISTANCE, 0.0);
|
||||
m_activeSwipe.pWorkspaceBegin->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
g_pInputManager->unconstrainMouse();
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the left");
|
||||
|
||||
pSwitchedTo = PWORKSPACEL;
|
||||
} else {
|
||||
// switch to right
|
||||
const auto RENDEROFFSET = PWORKSPACER ? PWORKSPACER->m_renderOffset->value() : Vector2D();
|
||||
|
||||
if (PWORKSPACER)
|
||||
m_activeSwipe.pMonitor->changeWorkspace(workspaceIDRight);
|
||||
else {
|
||||
m_activeSwipe.pMonitor->changeWorkspace(g_pCompositor->createNewWorkspace(workspaceIDRight, m_activeSwipe.pMonitor->m_id));
|
||||
PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
PWORKSPACER->rememberPrevWorkspace(m_activeSwipe.pWorkspaceBegin);
|
||||
}
|
||||
|
||||
PWORKSPACER->m_renderOffset->setValue(RENDEROFFSET);
|
||||
PWORKSPACER->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValue(RENDEROFFSETMIDDLE);
|
||||
if (VERTANIMS)
|
||||
*m_activeSwipe.pWorkspaceBegin->m_renderOffset = Vector2D(0.0, -YDISTANCE);
|
||||
else
|
||||
*m_activeSwipe.pWorkspaceBegin->m_renderOffset = Vector2D(-XDISTANCE, 0.0);
|
||||
m_activeSwipe.pWorkspaceBegin->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
g_pInputManager->unconstrainMouse();
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the right");
|
||||
|
||||
pSwitchedTo = PWORKSPACER;
|
||||
}
|
||||
m_activeSwipe.pWorkspaceBegin->rememberPrevWorkspace(pSwitchedTo);
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_activeSwipe.pMonitor.lock());
|
||||
|
||||
if (PWORKSPACEL)
|
||||
PWORKSPACEL->m_forceRendering = false;
|
||||
if (PWORKSPACER)
|
||||
PWORKSPACER->m_forceRendering = false;
|
||||
m_activeSwipe.pWorkspaceBegin->m_forceRendering = false;
|
||||
|
||||
m_activeSwipe.pWorkspaceBegin = nullptr;
|
||||
m_activeSwipe.initialDirection = 0;
|
||||
|
||||
g_pInputManager->refocus();
|
||||
|
||||
// apply alpha
|
||||
for (auto const& ls : g_pCompositor->m_lastMonitor->m_layerSurfaceLayers[2]) {
|
||||
*ls->m_alpha = pSwitchedTo->m_hasFullscreenWindow && pSwitchedTo->m_fullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void CInputManager::onSwipeUpdate(IPointer::SSwipeUpdateEvent e) {
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("swipeUpdate", e);
|
||||
|
||||
if (!m_activeSwipe.pWorkspaceBegin)
|
||||
return;
|
||||
static auto PSWIPEINVR = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_invert");
|
||||
const auto ANIMSTYLE = m_activeSwipe.pWorkspaceBegin->m_renderOffset->getStyle();
|
||||
const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert");
|
||||
|
||||
const double delta = m_activeSwipe.delta + (VERTANIMS ? (*PSWIPEINVR ? -e.delta.y : e.delta.y) : (*PSWIPEINVR ? -e.delta.x : e.delta.x));
|
||||
updateWorkspaceSwipe(delta);
|
||||
}
|
||||
|
||||
void CInputManager::updateWorkspaceSwipe(double delta) {
|
||||
static auto PSWIPEDIST = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_distance");
|
||||
static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
|
||||
static auto PSWIPEDIRLOCK = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_direction_lock");
|
||||
static auto PSWIPEDIRLOCKTHRESHOLD = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_direction_lock_threshold");
|
||||
static auto PSWIPEFOREVER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_forever");
|
||||
static auto PSWIPEUSER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_use_r");
|
||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||
|
||||
const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, sc<int64_t>(1LL), sc<int64_t>(UINT32_MAX));
|
||||
const auto XDISTANCE = m_activeSwipe.pMonitor->m_size.x + *PWORKSPACEGAP;
|
||||
const auto YDISTANCE = m_activeSwipe.pMonitor->m_size.y + *PWORKSPACEGAP;
|
||||
const auto ANIMSTYLE = m_activeSwipe.pWorkspaceBegin->m_renderOffset->getStyle();
|
||||
const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert");
|
||||
const double d = m_activeSwipe.delta - delta;
|
||||
m_activeSwipe.delta = delta;
|
||||
|
||||
m_activeSwipe.avgSpeed = (m_activeSwipe.avgSpeed * m_activeSwipe.speedPoints + abs(d)) / (m_activeSwipe.speedPoints + 1);
|
||||
m_activeSwipe.speedPoints++;
|
||||
|
||||
auto workspaceIDLeft = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r-1" : "m-1")).id;
|
||||
auto workspaceIDRight = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r+1" : "m+1")).id;
|
||||
|
||||
if ((workspaceIDLeft == WORKSPACE_INVALID || workspaceIDRight == WORKSPACE_INVALID || workspaceIDLeft == m_activeSwipe.pWorkspaceBegin->m_id) && !*PSWIPENEW) {
|
||||
m_activeSwipe.pWorkspaceBegin = nullptr; // invalidate the swipe
|
||||
return;
|
||||
}
|
||||
|
||||
m_activeSwipe.pWorkspaceBegin->m_forceRendering = true;
|
||||
|
||||
m_activeSwipe.delta = std::clamp(m_activeSwipe.delta, sc<double>(-SWIPEDISTANCE), sc<double>(SWIPEDISTANCE));
|
||||
|
||||
if ((m_activeSwipe.pWorkspaceBegin->m_id == workspaceIDLeft && *PSWIPENEW && (m_activeSwipe.delta < 0)) ||
|
||||
(m_activeSwipe.delta > 0 && m_activeSwipe.pWorkspaceBegin->getWindows() == 0 && workspaceIDRight <= m_activeSwipe.pWorkspaceBegin->m_id) ||
|
||||
(m_activeSwipe.delta < 0 && m_activeSwipe.pWorkspaceBegin->m_id <= workspaceIDLeft)) {
|
||||
|
||||
m_activeSwipe.delta = 0;
|
||||
g_pHyprRenderer->damageMonitor(m_activeSwipe.pMonitor.lock());
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, 0.0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*PSWIPEDIRLOCK) {
|
||||
if (m_activeSwipe.initialDirection != 0 && m_activeSwipe.initialDirection != (m_activeSwipe.delta < 0 ? -1 : 1))
|
||||
m_activeSwipe.delta = 0;
|
||||
else if (m_activeSwipe.initialDirection == 0 && abs(m_activeSwipe.delta) > *PSWIPEDIRLOCKTHRESHOLD)
|
||||
m_activeSwipe.initialDirection = m_activeSwipe.delta < 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
if (m_activeSwipe.delta < 0) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
if (workspaceIDLeft > m_activeSwipe.pWorkspaceBegin->m_id || !PWORKSPACE) {
|
||||
if (*PSWIPENEW) {
|
||||
g_pHyprRenderer->damageMonitor(m_activeSwipe.pMonitor.lock());
|
||||
|
||||
if (VERTANIMS)
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_activeSwipe.delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
else
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(((-m_activeSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0));
|
||||
|
||||
m_activeSwipe.pWorkspaceBegin->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
m_activeSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
PWORKSPACE->m_forceRendering = true;
|
||||
PWORKSPACE->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight && workspaceIDRight != m_activeSwipe.pWorkspaceBegin->m_id) {
|
||||
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
if (PWORKSPACER) {
|
||||
PWORKSPACER->m_forceRendering = false;
|
||||
PWORKSPACER->m_alpha->setValueAndWarp(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
if (VERTANIMS) {
|
||||
PWORKSPACE->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_activeSwipe.delta) / SWIPEDISTANCE) * YDISTANCE - YDISTANCE));
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_activeSwipe.delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
} else {
|
||||
PWORKSPACE->m_renderOffset->setValueAndWarp(Vector2D(((-m_activeSwipe.delta) / SWIPEDISTANCE) * XDISTANCE - XDISTANCE, 0.0));
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(((-m_activeSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0));
|
||||
}
|
||||
|
||||
PWORKSPACE->updateWindowDecos();
|
||||
} else {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
if (workspaceIDRight < m_activeSwipe.pWorkspaceBegin->m_id || !PWORKSPACE) {
|
||||
if (*PSWIPENEW) {
|
||||
g_pHyprRenderer->damageMonitor(m_activeSwipe.pMonitor.lock());
|
||||
|
||||
if (VERTANIMS)
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_activeSwipe.delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
else
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(((-m_activeSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0));
|
||||
|
||||
m_activeSwipe.pWorkspaceBegin->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
m_activeSwipe.delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
PWORKSPACE->m_forceRendering = true;
|
||||
PWORKSPACE->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight && workspaceIDLeft != m_activeSwipe.pWorkspaceBegin->m_id) {
|
||||
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
if (PWORKSPACEL) {
|
||||
PWORKSPACEL->m_forceRendering = false;
|
||||
PWORKSPACEL->m_alpha->setValueAndWarp(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
if (VERTANIMS) {
|
||||
PWORKSPACE->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_activeSwipe.delta) / SWIPEDISTANCE) * YDISTANCE + YDISTANCE));
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_activeSwipe.delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
} else {
|
||||
PWORKSPACE->m_renderOffset->setValueAndWarp(Vector2D(((-m_activeSwipe.delta) / SWIPEDISTANCE) * XDISTANCE + XDISTANCE, 0.0));
|
||||
m_activeSwipe.pWorkspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(((-m_activeSwipe.delta) / SWIPEDISTANCE) * XDISTANCE, 0.0));
|
||||
}
|
||||
|
||||
PWORKSPACE->updateWindowDecos();
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_activeSwipe.pMonitor.lock());
|
||||
|
||||
m_activeSwipe.pWorkspaceBegin->updateWindowDecos();
|
||||
|
||||
if (*PSWIPEFOREVER) {
|
||||
if (abs(m_activeSwipe.delta) >= SWIPEDISTANCE) {
|
||||
onSwipeEnd({});
|
||||
beginWorkspaceSwipe();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,9 +7,10 @@
|
||||
#include "../../helpers/Monitor.hpp"
|
||||
#include "../../devices/ITouch.hpp"
|
||||
#include "../SeatManager.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/animation/AnimationManager.hpp"
|
||||
#include "../HookSystemManager.hpp"
|
||||
#include "debug/Log.hpp"
|
||||
#include "UnifiedWorkspaceSwipeGesture.hpp"
|
||||
|
||||
void CInputManager::onTouchDown(ITouch::SDownEvent e) {
|
||||
m_lastInputTouch = true;
|
||||
@ -39,7 +40,7 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
|
||||
}
|
||||
|
||||
// Don't propagate new touches when a workspace swipe is in progress.
|
||||
if (m_activeSwipe.pWorkspaceBegin) {
|
||||
if (g_pUnifiedWorkspaceSwipe->isGestureInProgress()) {
|
||||
return;
|
||||
// TODO: Don't swipe if you touched a floating window.
|
||||
} else if (*PSWIPETOUCH && (m_foundLSToFocus.expired() || m_foundLSToFocus->m_layer <= 1) && !g_pSessionLockManager->isSessionLocked()) {
|
||||
@ -50,13 +51,13 @@ void CInputManager::onTouchDown(ITouch::SDownEvent e) {
|
||||
const double TARGETRIGHT = 1 - (((VERTANIMS ? gapsOut.m_bottom : gapsOut.m_right) + *PBORDERSIZE) / (VERTANIMS ? PMONITOR->m_size.y : PMONITOR->m_size.x));
|
||||
const double POSITION = (VERTANIMS ? e.pos.y : e.pos.x);
|
||||
if (POSITION < TARGETLEFT || POSITION > TARGETRIGHT) {
|
||||
beginWorkspaceSwipe();
|
||||
m_activeSwipe.touch_id = e.touchID;
|
||||
g_pUnifiedWorkspaceSwipe->begin();
|
||||
g_pUnifiedWorkspaceSwipe->m_touchID = e.touchID;
|
||||
// Set the initial direction based on which edge you started from
|
||||
if (POSITION > 0.5)
|
||||
m_activeSwipe.initialDirection = *PSWIPEINVR ? -1 : 1;
|
||||
g_pUnifiedWorkspaceSwipe->m_initialDirection = *PSWIPEINVR ? -1 : 1;
|
||||
else
|
||||
m_activeSwipe.initialDirection = *PSWIPEINVR ? 1 : -1;
|
||||
g_pUnifiedWorkspaceSwipe->m_initialDirection = *PSWIPEINVR ? 1 : -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -109,10 +110,10 @@ void CInputManager::onTouchUp(ITouch::SUpEvent e) {
|
||||
m_lastInputTouch = true;
|
||||
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("touchUp", e);
|
||||
if (m_activeSwipe.pWorkspaceBegin) {
|
||||
if (g_pUnifiedWorkspaceSwipe->isGestureInProgress()) {
|
||||
// If there was a swipe from this finger, end it.
|
||||
if (e.touchID == m_activeSwipe.touch_id)
|
||||
endWorkspaceSwipe();
|
||||
if (e.touchID == g_pUnifiedWorkspaceSwipe->m_touchID)
|
||||
g_pUnifiedWorkspaceSwipe->end();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -124,30 +125,30 @@ void CInputManager::onTouchMove(ITouch::SMotionEvent e) {
|
||||
m_lastInputTouch = true;
|
||||
|
||||
EMIT_HOOK_EVENT_CANCELLABLE("touchMove", e);
|
||||
if (m_activeSwipe.pWorkspaceBegin) {
|
||||
if (g_pUnifiedWorkspaceSwipe->isGestureInProgress()) {
|
||||
// Do nothing if this is using a different finger.
|
||||
if (e.touchID != m_activeSwipe.touch_id)
|
||||
if (e.touchID != g_pUnifiedWorkspaceSwipe->m_touchID)
|
||||
return;
|
||||
|
||||
const auto ANIMSTYLE = m_activeSwipe.pWorkspaceBegin->m_renderOffset->getStyle();
|
||||
const auto ANIMSTYLE = g_pUnifiedWorkspaceSwipe->m_workspaceBegin->m_renderOffset->getStyle();
|
||||
const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert");
|
||||
static auto PSWIPEINVR = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_touch_invert");
|
||||
static auto PSWIPEDIST = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_distance");
|
||||
const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, sc<int64_t>(1LL), sc<int64_t>(UINT32_MAX));
|
||||
// Handle the workspace swipe if there is one
|
||||
if (m_activeSwipe.initialDirection == -1) {
|
||||
if (g_pUnifiedWorkspaceSwipe->m_initialDirection == -1) {
|
||||
if (*PSWIPEINVR)
|
||||
// go from 0 to -SWIPEDISTANCE
|
||||
updateWorkspaceSwipe(SWIPEDISTANCE * ((VERTANIMS ? e.pos.y : e.pos.x) - 1));
|
||||
g_pUnifiedWorkspaceSwipe->update(SWIPEDISTANCE * ((VERTANIMS ? e.pos.y : e.pos.x) - 1));
|
||||
else
|
||||
// go from 0 to -SWIPEDISTANCE
|
||||
updateWorkspaceSwipe(SWIPEDISTANCE * (-1 * (VERTANIMS ? e.pos.y : e.pos.x)));
|
||||
g_pUnifiedWorkspaceSwipe->update(SWIPEDISTANCE * (-1 * (VERTANIMS ? e.pos.y : e.pos.x)));
|
||||
} else if (*PSWIPEINVR)
|
||||
// go from 0 to SWIPEDISTANCE
|
||||
updateWorkspaceSwipe(SWIPEDISTANCE * (VERTANIMS ? e.pos.y : e.pos.x));
|
||||
g_pUnifiedWorkspaceSwipe->update(SWIPEDISTANCE * (VERTANIMS ? e.pos.y : e.pos.x));
|
||||
else
|
||||
// go from 0 to SWIPEDISTANCE
|
||||
updateWorkspaceSwipe(SWIPEDISTANCE * (1 - (VERTANIMS ? e.pos.y : e.pos.x)));
|
||||
g_pUnifiedWorkspaceSwipe->update(SWIPEDISTANCE * (1 - (VERTANIMS ? e.pos.y : e.pos.x)));
|
||||
return;
|
||||
}
|
||||
if (m_touchData.touchFocusLockSurface) {
|
||||
|
||||
313
src/managers/input/UnifiedWorkspaceSwipeGesture.cpp
Normal file
313
src/managers/input/UnifiedWorkspaceSwipeGesture.cpp
Normal file
@ -0,0 +1,313 @@
|
||||
#include "UnifiedWorkspaceSwipeGesture.hpp"
|
||||
|
||||
#include "../../Compositor.hpp"
|
||||
#include "../../render/Renderer.hpp"
|
||||
#include "InputManager.hpp"
|
||||
|
||||
bool CUnifiedWorkspaceSwipeGesture::isGestureInProgress() {
|
||||
return m_workspaceBegin;
|
||||
}
|
||||
|
||||
void CUnifiedWorkspaceSwipeGesture::begin() {
|
||||
if (isGestureInProgress())
|
||||
return;
|
||||
|
||||
const auto PWORKSPACE = g_pCompositor->m_lastMonitor->m_activeWorkspace;
|
||||
|
||||
Debug::log(LOG, "CUnifiedWorkspaceSwipeGesture::begin: Starting a swipe from {}", PWORKSPACE->m_name);
|
||||
|
||||
m_workspaceBegin = PWORKSPACE;
|
||||
m_delta = 0;
|
||||
m_monitor = g_pCompositor->m_lastMonitor;
|
||||
m_avgSpeed = 0;
|
||||
m_speedPoints = 0;
|
||||
|
||||
if (PWORKSPACE->m_hasFullscreenWindow) {
|
||||
for (auto const& ls : g_pCompositor->m_lastMonitor->m_layerSurfaceLayers[2]) {
|
||||
*ls->m_alpha = 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CUnifiedWorkspaceSwipeGesture::update(double delta) {
|
||||
if (!isGestureInProgress())
|
||||
return;
|
||||
|
||||
static auto PSWIPEDIST = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_distance");
|
||||
static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
|
||||
static auto PSWIPEDIRLOCK = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_direction_lock");
|
||||
static auto PSWIPEDIRLOCKTHRESHOLD = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_direction_lock_threshold");
|
||||
static auto PSWIPEFOREVER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_forever");
|
||||
static auto PSWIPEUSER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_use_r");
|
||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||
|
||||
const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, sc<int64_t>(1LL), sc<int64_t>(UINT32_MAX));
|
||||
const auto XDISTANCE = m_monitor->m_size.x + *PWORKSPACEGAP;
|
||||
const auto YDISTANCE = m_monitor->m_size.y + *PWORKSPACEGAP;
|
||||
const auto ANIMSTYLE = m_workspaceBegin->m_renderOffset->getStyle();
|
||||
const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert");
|
||||
const double d = m_delta - delta;
|
||||
m_delta = delta;
|
||||
|
||||
m_avgSpeed = (m_avgSpeed * m_speedPoints + abs(d)) / (m_speedPoints + 1);
|
||||
m_speedPoints++;
|
||||
|
||||
auto workspaceIDLeft = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r-1" : "m-1")).id;
|
||||
auto workspaceIDRight = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r+1" : "m+1")).id;
|
||||
|
||||
if ((workspaceIDLeft == WORKSPACE_INVALID || workspaceIDRight == WORKSPACE_INVALID || workspaceIDLeft == m_workspaceBegin->m_id) && !*PSWIPENEW) {
|
||||
m_workspaceBegin = nullptr; // invalidate the swipe
|
||||
return;
|
||||
}
|
||||
|
||||
m_workspaceBegin->m_forceRendering = true;
|
||||
|
||||
m_delta = std::clamp(m_delta, sc<double>(-SWIPEDISTANCE), sc<double>(SWIPEDISTANCE));
|
||||
|
||||
if ((m_workspaceBegin->m_id == workspaceIDLeft && *PSWIPENEW && (m_delta < 0)) ||
|
||||
(m_delta > 0 && m_workspaceBegin->getWindows() == 0 && workspaceIDRight <= m_workspaceBegin->m_id) || (m_delta < 0 && m_workspaceBegin->m_id <= workspaceIDLeft)) {
|
||||
|
||||
m_delta = 0;
|
||||
g_pHyprRenderer->damageMonitor(m_monitor.lock());
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, 0.0));
|
||||
return;
|
||||
}
|
||||
|
||||
if (*PSWIPEDIRLOCK) {
|
||||
if (m_initialDirection != 0 && m_initialDirection != (m_delta < 0 ? -1 : 1))
|
||||
m_delta = 0;
|
||||
else if (m_initialDirection == 0 && abs(m_delta) > *PSWIPEDIRLOCKTHRESHOLD)
|
||||
m_initialDirection = m_delta < 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
if (m_delta < 0) {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
if (workspaceIDLeft > m_workspaceBegin->m_id || !PWORKSPACE) {
|
||||
if (*PSWIPENEW) {
|
||||
g_pHyprRenderer->damageMonitor(m_monitor.lock());
|
||||
|
||||
if (VERTANIMS)
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
else
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(((-m_delta) / SWIPEDISTANCE) * XDISTANCE, 0.0));
|
||||
|
||||
m_workspaceBegin->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
m_delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
PWORKSPACE->m_forceRendering = true;
|
||||
PWORKSPACE->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight && workspaceIDRight != m_workspaceBegin->m_id) {
|
||||
const auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
if (PWORKSPACER) {
|
||||
PWORKSPACER->m_forceRendering = false;
|
||||
PWORKSPACER->m_alpha->setValueAndWarp(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
if (VERTANIMS) {
|
||||
PWORKSPACE->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_delta) / SWIPEDISTANCE) * YDISTANCE - YDISTANCE));
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
} else {
|
||||
PWORKSPACE->m_renderOffset->setValueAndWarp(Vector2D(((-m_delta) / SWIPEDISTANCE) * XDISTANCE - XDISTANCE, 0.0));
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(((-m_delta) / SWIPEDISTANCE) * XDISTANCE, 0.0));
|
||||
}
|
||||
|
||||
PWORKSPACE->updateWindowDecos();
|
||||
} else {
|
||||
const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
|
||||
if (workspaceIDRight < m_workspaceBegin->m_id || !PWORKSPACE) {
|
||||
if (*PSWIPENEW) {
|
||||
g_pHyprRenderer->damageMonitor(m_monitor.lock());
|
||||
|
||||
if (VERTANIMS)
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
else
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(((-m_delta) / SWIPEDISTANCE) * XDISTANCE, 0.0));
|
||||
|
||||
m_workspaceBegin->updateWindowDecos();
|
||||
return;
|
||||
}
|
||||
m_delta = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
PWORKSPACE->m_forceRendering = true;
|
||||
PWORKSPACE->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
if (workspaceIDLeft != workspaceIDRight && workspaceIDLeft != m_workspaceBegin->m_id) {
|
||||
const auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
|
||||
if (PWORKSPACEL) {
|
||||
PWORKSPACEL->m_forceRendering = false;
|
||||
PWORKSPACEL->m_alpha->setValueAndWarp(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
if (VERTANIMS) {
|
||||
PWORKSPACE->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_delta) / SWIPEDISTANCE) * YDISTANCE + YDISTANCE));
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0.0, ((-m_delta) / SWIPEDISTANCE) * YDISTANCE));
|
||||
} else {
|
||||
PWORKSPACE->m_renderOffset->setValueAndWarp(Vector2D(((-m_delta) / SWIPEDISTANCE) * XDISTANCE + XDISTANCE, 0.0));
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(((-m_delta) / SWIPEDISTANCE) * XDISTANCE, 0.0));
|
||||
}
|
||||
|
||||
PWORKSPACE->updateWindowDecos();
|
||||
}
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_monitor.lock());
|
||||
|
||||
m_workspaceBegin->updateWindowDecos();
|
||||
|
||||
if (*PSWIPEFOREVER) {
|
||||
if (abs(m_delta) >= SWIPEDISTANCE) {
|
||||
end();
|
||||
begin();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CUnifiedWorkspaceSwipeGesture::end() {
|
||||
if (!isGestureInProgress())
|
||||
return;
|
||||
|
||||
static auto PSWIPEPERC = CConfigValue<Hyprlang::FLOAT>("gestures:workspace_swipe_cancel_ratio");
|
||||
static auto PSWIPEDIST = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_distance");
|
||||
static auto PSWIPEFORC = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_min_speed_to_force");
|
||||
static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
|
||||
static auto PSWIPEUSER = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_use_r");
|
||||
static auto PWORKSPACEGAP = CConfigValue<Hyprlang::INT>("general:gaps_workspaces");
|
||||
const auto ANIMSTYLE = m_workspaceBegin->m_renderOffset->getStyle();
|
||||
const bool VERTANIMS = ANIMSTYLE == "slidevert" || ANIMSTYLE.starts_with("slidefadevert");
|
||||
|
||||
// commit
|
||||
auto workspaceIDLeft = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r-1" : "m-1")).id;
|
||||
auto workspaceIDRight = getWorkspaceIDNameFromString((*PSWIPEUSER ? "r+1" : "m+1")).id;
|
||||
const auto SWIPEDISTANCE = std::clamp(*PSWIPEDIST, sc<int64_t>(1LL), sc<int64_t>(UINT32_MAX));
|
||||
|
||||
// If we've been swiping off the right end with PSWIPENEW enabled, there is
|
||||
// no workspace there yet, and we need to choose an ID for a new one now.
|
||||
if (workspaceIDRight <= m_workspaceBegin->m_id && *PSWIPENEW)
|
||||
workspaceIDRight = getWorkspaceIDNameFromString("r+1").id;
|
||||
|
||||
auto PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight); // not guaranteed if PSWIPENEW || PSWIPENUMBER
|
||||
auto PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft); // not guaranteed if PSWIPENUMBER
|
||||
|
||||
const auto RENDEROFFSETMIDDLE = m_workspaceBegin->m_renderOffset->value();
|
||||
const auto XDISTANCE = m_monitor->m_size.x + *PWORKSPACEGAP;
|
||||
const auto YDISTANCE = m_monitor->m_size.y + *PWORKSPACEGAP;
|
||||
|
||||
PHLWORKSPACE pSwitchedTo = nullptr;
|
||||
|
||||
if ((abs(m_delta) < SWIPEDISTANCE * *PSWIPEPERC && (*PSWIPEFORC == 0 || (*PSWIPEFORC != 0 && m_avgSpeed < *PSWIPEFORC))) || abs(m_delta) < 2) {
|
||||
// revert
|
||||
if (abs(m_delta) < 2) {
|
||||
if (PWORKSPACEL)
|
||||
PWORKSPACEL->m_renderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
if (PWORKSPACER)
|
||||
PWORKSPACER->m_renderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
m_workspaceBegin->m_renderOffset->setValueAndWarp(Vector2D(0, 0));
|
||||
} else {
|
||||
if (m_delta < 0) {
|
||||
// to left
|
||||
|
||||
if (PWORKSPACEL) {
|
||||
if (VERTANIMS)
|
||||
*PWORKSPACEL->m_renderOffset = Vector2D{0.0, -YDISTANCE};
|
||||
else
|
||||
*PWORKSPACEL->m_renderOffset = Vector2D{-XDISTANCE, 0.0};
|
||||
}
|
||||
} else if (PWORKSPACER) {
|
||||
// to right
|
||||
if (VERTANIMS)
|
||||
*PWORKSPACER->m_renderOffset = Vector2D{0.0, YDISTANCE};
|
||||
else
|
||||
*PWORKSPACER->m_renderOffset = Vector2D{XDISTANCE, 0.0};
|
||||
}
|
||||
|
||||
*m_workspaceBegin->m_renderOffset = Vector2D();
|
||||
}
|
||||
|
||||
pSwitchedTo = m_workspaceBegin;
|
||||
} else if (m_delta < 0) {
|
||||
// switch to left
|
||||
const auto RENDEROFFSET = PWORKSPACEL ? PWORKSPACEL->m_renderOffset->value() : Vector2D();
|
||||
|
||||
if (PWORKSPACEL)
|
||||
m_monitor->changeWorkspace(workspaceIDLeft);
|
||||
else {
|
||||
m_monitor->changeWorkspace(g_pCompositor->createNewWorkspace(workspaceIDLeft, m_monitor->m_id));
|
||||
PWORKSPACEL = g_pCompositor->getWorkspaceByID(workspaceIDLeft);
|
||||
PWORKSPACEL->rememberPrevWorkspace(m_workspaceBegin);
|
||||
}
|
||||
|
||||
PWORKSPACEL->m_renderOffset->setValue(RENDEROFFSET);
|
||||
PWORKSPACEL->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
m_workspaceBegin->m_renderOffset->setValue(RENDEROFFSETMIDDLE);
|
||||
if (VERTANIMS)
|
||||
*m_workspaceBegin->m_renderOffset = Vector2D(0.0, YDISTANCE);
|
||||
else
|
||||
*m_workspaceBegin->m_renderOffset = Vector2D(XDISTANCE, 0.0);
|
||||
m_workspaceBegin->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
g_pInputManager->unconstrainMouse();
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the left");
|
||||
|
||||
pSwitchedTo = PWORKSPACEL;
|
||||
} else {
|
||||
// switch to right
|
||||
const auto RENDEROFFSET = PWORKSPACER ? PWORKSPACER->m_renderOffset->value() : Vector2D();
|
||||
|
||||
if (PWORKSPACER)
|
||||
m_monitor->changeWorkspace(workspaceIDRight);
|
||||
else {
|
||||
m_monitor->changeWorkspace(g_pCompositor->createNewWorkspace(workspaceIDRight, m_monitor->m_id));
|
||||
PWORKSPACER = g_pCompositor->getWorkspaceByID(workspaceIDRight);
|
||||
PWORKSPACER->rememberPrevWorkspace(m_workspaceBegin);
|
||||
}
|
||||
|
||||
PWORKSPACER->m_renderOffset->setValue(RENDEROFFSET);
|
||||
PWORKSPACER->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
m_workspaceBegin->m_renderOffset->setValue(RENDEROFFSETMIDDLE);
|
||||
if (VERTANIMS)
|
||||
*m_workspaceBegin->m_renderOffset = Vector2D(0.0, -YDISTANCE);
|
||||
else
|
||||
*m_workspaceBegin->m_renderOffset = Vector2D(-XDISTANCE, 0.0);
|
||||
m_workspaceBegin->m_alpha->setValueAndWarp(1.f);
|
||||
|
||||
g_pInputManager->unconstrainMouse();
|
||||
|
||||
Debug::log(LOG, "Ended swipe to the right");
|
||||
|
||||
pSwitchedTo = PWORKSPACER;
|
||||
}
|
||||
m_workspaceBegin->rememberPrevWorkspace(pSwitchedTo);
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_monitor.lock());
|
||||
|
||||
if (PWORKSPACEL)
|
||||
PWORKSPACEL->m_forceRendering = false;
|
||||
if (PWORKSPACER)
|
||||
PWORKSPACER->m_forceRendering = false;
|
||||
m_workspaceBegin->m_forceRendering = false;
|
||||
|
||||
m_workspaceBegin = nullptr;
|
||||
m_initialDirection = 0;
|
||||
|
||||
g_pInputManager->refocus();
|
||||
|
||||
// apply alpha
|
||||
for (auto const& ls : g_pCompositor->m_lastMonitor->m_layerSurfaceLayers[2]) {
|
||||
*ls->m_alpha = pSwitchedTo->m_hasFullscreenWindow && pSwitchedTo->m_fullscreenMode == FSMODE_FULLSCREEN ? 0.f : 1.f;
|
||||
}
|
||||
}
|
||||
28
src/managers/input/UnifiedWorkspaceSwipeGesture.hpp
Normal file
28
src/managers/input/UnifiedWorkspaceSwipeGesture.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../helpers/memory/Memory.hpp"
|
||||
#include "../../desktop/DesktopTypes.hpp"
|
||||
|
||||
class CUnifiedWorkspaceSwipeGesture {
|
||||
public:
|
||||
void begin();
|
||||
void update(double delta);
|
||||
void end();
|
||||
|
||||
bool isGestureInProgress();
|
||||
|
||||
private:
|
||||
PHLWORKSPACE m_workspaceBegin = nullptr;
|
||||
PHLMONITORREF m_monitor;
|
||||
|
||||
double m_delta = 0;
|
||||
int m_initialDirection = 0;
|
||||
float m_avgSpeed = 0;
|
||||
int m_speedPoints = 0;
|
||||
int m_touchID = 0;
|
||||
|
||||
friend class CWorkspaceSwipeGesture;
|
||||
friend class CInputManager;
|
||||
};
|
||||
|
||||
inline UP<CUnifiedWorkspaceSwipeGesture> g_pUnifiedWorkspaceSwipe = makeUnique<CUnifiedWorkspaceSwipeGesture>();
|
||||
17
src/managers/input/trackpad/GestureTypes.hpp
Normal file
17
src/managers/input/trackpad/GestureTypes.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum eTrackpadGestureDirection : uint8_t {
|
||||
TRACKPAD_GESTURE_DIR_NONE = 0,
|
||||
TRACKPAD_GESTURE_DIR_SWIPE,
|
||||
TRACKPAD_GESTURE_DIR_LEFT,
|
||||
TRACKPAD_GESTURE_DIR_RIGHT,
|
||||
TRACKPAD_GESTURE_DIR_UP,
|
||||
TRACKPAD_GESTURE_DIR_DOWN,
|
||||
TRACKPAD_GESTURE_DIR_VERTICAL,
|
||||
TRACKPAD_GESTURE_DIR_HORIZONTAL,
|
||||
TRACKPAD_GESTURE_DIR_PINCH,
|
||||
TRACKPAD_GESTURE_DIR_PINCH_OUT,
|
||||
TRACKPAD_GESTURE_DIR_PINCH_IN,
|
||||
};
|
||||
221
src/managers/input/trackpad/TrackpadGestures.cpp
Normal file
221
src/managers/input/trackpad/TrackpadGestures.cpp
Normal file
@ -0,0 +1,221 @@
|
||||
#include "TrackpadGestures.hpp"
|
||||
|
||||
#include "../InputManager.hpp"
|
||||
|
||||
#include <ranges>
|
||||
|
||||
void CTrackpadGestures::clearGestures() {
|
||||
m_gestures.clear();
|
||||
}
|
||||
|
||||
eTrackpadGestureDirection CTrackpadGestures::dirForString(const std::string_view& s) {
|
||||
std::string lc = std::string{s};
|
||||
std::ranges::transform(lc, lc.begin(), ::tolower);
|
||||
|
||||
if (lc == "swipe")
|
||||
return TRACKPAD_GESTURE_DIR_SWIPE;
|
||||
if (lc == "left" || lc == "l")
|
||||
return TRACKPAD_GESTURE_DIR_LEFT;
|
||||
if (lc == "right" || lc == "r")
|
||||
return TRACKPAD_GESTURE_DIR_RIGHT;
|
||||
if (lc == "up" || lc == "u" || lc == "top" || lc == "t")
|
||||
return TRACKPAD_GESTURE_DIR_UP;
|
||||
if (lc == "down" || lc == "d" || lc == "bottom" || lc == "b")
|
||||
return TRACKPAD_GESTURE_DIR_DOWN;
|
||||
if (lc == "horizontal" || lc == "horiz")
|
||||
return TRACKPAD_GESTURE_DIR_HORIZONTAL;
|
||||
if (lc == "vertical" || lc == "vert")
|
||||
return TRACKPAD_GESTURE_DIR_VERTICAL;
|
||||
if (lc == "pinch")
|
||||
return TRACKPAD_GESTURE_DIR_PINCH;
|
||||
if (lc == "pinchin" || lc == "zoomin")
|
||||
return TRACKPAD_GESTURE_DIR_PINCH_IN;
|
||||
if (lc == "pinchout" || lc == "zoomout")
|
||||
return TRACKPAD_GESTURE_DIR_PINCH_OUT;
|
||||
|
||||
return TRACKPAD_GESTURE_DIR_NONE;
|
||||
}
|
||||
|
||||
const char* CTrackpadGestures::stringForDir(eTrackpadGestureDirection dir) {
|
||||
switch (dir) {
|
||||
case TRACKPAD_GESTURE_DIR_HORIZONTAL: return "HORIZONTAL";
|
||||
case TRACKPAD_GESTURE_DIR_VERTICAL: return "VERTICAL";
|
||||
case TRACKPAD_GESTURE_DIR_LEFT: return "LEFT";
|
||||
case TRACKPAD_GESTURE_DIR_RIGHT: return "RIGHT";
|
||||
case TRACKPAD_GESTURE_DIR_UP: return "UP";
|
||||
case TRACKPAD_GESTURE_DIR_DOWN: return "DOWN";
|
||||
case TRACKPAD_GESTURE_DIR_SWIPE: return "SWIPE";
|
||||
case TRACKPAD_GESTURE_DIR_PINCH: return "PINCH";
|
||||
case TRACKPAD_GESTURE_DIR_PINCH_IN: return "PINCH_IN";
|
||||
case TRACKPAD_GESTURE_DIR_PINCH_OUT: return "PINCH_OUT";
|
||||
default: return "ERROR";
|
||||
}
|
||||
return "ERROR";
|
||||
}
|
||||
|
||||
std::expected<void, std::string> CTrackpadGestures::addGesture(UP<ITrackpadGesture>&& gesture, size_t fingerCount, eTrackpadGestureDirection direction, uint32_t modMask,
|
||||
float deltaScale) {
|
||||
for (const auto& g : m_gestures) {
|
||||
if (g->fingerCount != fingerCount)
|
||||
continue;
|
||||
|
||||
if (g->modMask != modMask)
|
||||
continue;
|
||||
|
||||
eTrackpadGestureDirection axis = TRACKPAD_GESTURE_DIR_NONE;
|
||||
switch (direction) {
|
||||
case TRACKPAD_GESTURE_DIR_UP:
|
||||
case TRACKPAD_GESTURE_DIR_DOWN:
|
||||
case TRACKPAD_GESTURE_DIR_VERTICAL: axis = TRACKPAD_GESTURE_DIR_VERTICAL; break;
|
||||
case TRACKPAD_GESTURE_DIR_LEFT:
|
||||
case TRACKPAD_GESTURE_DIR_RIGHT:
|
||||
case TRACKPAD_GESTURE_DIR_HORIZONTAL: axis = TRACKPAD_GESTURE_DIR_HORIZONTAL; break;
|
||||
case TRACKPAD_GESTURE_DIR_SWIPE: axis = TRACKPAD_GESTURE_DIR_SWIPE; break;
|
||||
case TRACKPAD_GESTURE_DIR_PINCH:
|
||||
case TRACKPAD_GESTURE_DIR_PINCH_IN:
|
||||
case TRACKPAD_GESTURE_DIR_PINCH_OUT: axis = TRACKPAD_GESTURE_DIR_PINCH; break;
|
||||
default: TRACKPAD_GESTURE_DIR_NONE; break;
|
||||
}
|
||||
|
||||
if (g->direction == axis || g->direction == direction ||
|
||||
((axis == TRACKPAD_GESTURE_DIR_VERTICAL || axis == TRACKPAD_GESTURE_DIR_HORIZONTAL) && g->direction == TRACKPAD_GESTURE_DIR_SWIPE)) {
|
||||
return std::unexpected(
|
||||
std::format("Gesture will be overshadowed by a previous gesture. Previous {} shadows new {}", stringForDir(g->direction), stringForDir(direction)));
|
||||
}
|
||||
}
|
||||
|
||||
m_gestures.emplace_back(makeShared<CTrackpadGestures::SGestureData>(std::move(gesture), fingerCount, modMask, direction, deltaScale));
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void CTrackpadGestures::gestureBegin(const IPointer::SSwipeBeginEvent& e) {
|
||||
if (m_activeGesture) {
|
||||
Debug::log(ERR, "CTrackpadGestures::gestureBegin (swipe) but m_activeGesture is already present");
|
||||
return;
|
||||
}
|
||||
|
||||
m_gestureFindFailed = false;
|
||||
|
||||
// nothing here. We need to wait for the first update to determine the delta.
|
||||
}
|
||||
|
||||
void CTrackpadGestures::gestureUpdate(const IPointer::SSwipeUpdateEvent& e) {
|
||||
if (m_gestureFindFailed)
|
||||
return;
|
||||
|
||||
// 5 was chosen because I felt like that's a good number.
|
||||
if (!m_activeGesture && (std::abs(e.delta.x) < 5 && std::abs(e.delta.y) < 5)) {
|
||||
Debug::log(TRACE, "CTrackpadGestures::gestureUpdate (swipe): gesture delta too small to start considering, waiting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_activeGesture) {
|
||||
// try to find a gesture that matches our current state
|
||||
|
||||
auto direction = TRACKPAD_GESTURE_DIR_NONE;
|
||||
auto axis = std::abs(e.delta.x) > std::abs(e.delta.y) ? TRACKPAD_GESTURE_DIR_HORIZONTAL : TRACKPAD_GESTURE_DIR_VERTICAL;
|
||||
|
||||
if (axis == TRACKPAD_GESTURE_DIR_HORIZONTAL)
|
||||
direction = e.delta.x < 0 ? TRACKPAD_GESTURE_DIR_LEFT : TRACKPAD_GESTURE_DIR_RIGHT;
|
||||
else
|
||||
direction = e.delta.y < 0 ? TRACKPAD_GESTURE_DIR_UP : TRACKPAD_GESTURE_DIR_DOWN;
|
||||
|
||||
const auto MODS = g_pInputManager->getModsFromAllKBs();
|
||||
|
||||
for (const auto& g : m_gestures) {
|
||||
if (g->direction != axis && g->direction != direction && g->direction != TRACKPAD_GESTURE_DIR_SWIPE)
|
||||
continue;
|
||||
|
||||
if (g->fingerCount != e.fingers)
|
||||
continue;
|
||||
|
||||
if (g->modMask != MODS)
|
||||
continue;
|
||||
|
||||
m_activeGesture = g;
|
||||
g->currentDirection = g->gesture->isDirectionSensitive() ? g->direction : direction;
|
||||
m_activeGesture->gesture->begin({.swipe = &e, .direction = direction, .scale = g->deltaScale});
|
||||
break;
|
||||
}
|
||||
|
||||
if (!m_activeGesture) {
|
||||
m_gestureFindFailed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_activeGesture->gesture->update({.swipe = &e, .direction = m_activeGesture->currentDirection, .scale = m_activeGesture->deltaScale});
|
||||
}
|
||||
|
||||
void CTrackpadGestures::gestureEnd(const IPointer::SSwipeEndEvent& e) {
|
||||
if (!m_activeGesture)
|
||||
return;
|
||||
|
||||
m_activeGesture->gesture->end({.swipe = &e, .direction = m_activeGesture->direction, .scale = m_activeGesture->deltaScale});
|
||||
|
||||
m_activeGesture.reset();
|
||||
}
|
||||
|
||||
void CTrackpadGestures::gestureBegin(const IPointer::SPinchBeginEvent& e) {
|
||||
if (m_activeGesture) {
|
||||
Debug::log(ERR, "CTrackpadGestures::gestureBegin (pinch) but m_activeGesture is already present");
|
||||
return;
|
||||
}
|
||||
|
||||
m_gestureFindFailed = false;
|
||||
|
||||
// nothing here. We need to wait for the first update to determine the delta.
|
||||
}
|
||||
|
||||
void CTrackpadGestures::gestureUpdate(const IPointer::SPinchUpdateEvent& e) {
|
||||
if (m_gestureFindFailed)
|
||||
return;
|
||||
|
||||
// 0.1 was chosen because I felt like that's a good number.
|
||||
if (!m_activeGesture && std::abs(e.scale - 1.F) < 0.1) {
|
||||
Debug::log(TRACE, "CTrackpadGestures::gestureUpdate (pinch): gesture delta too small to start considering, waiting");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_activeGesture) {
|
||||
// try to find a gesture that matches our current state
|
||||
|
||||
auto direction = e.scale < 1.F ? TRACKPAD_GESTURE_DIR_PINCH_OUT : TRACKPAD_GESTURE_DIR_PINCH_IN;
|
||||
auto axis = TRACKPAD_GESTURE_DIR_PINCH;
|
||||
|
||||
const auto MODS = g_pInputManager->getModsFromAllKBs();
|
||||
|
||||
for (const auto& g : m_gestures) {
|
||||
if (g->direction != axis && g->direction != direction)
|
||||
continue;
|
||||
|
||||
if (g->fingerCount != e.fingers)
|
||||
continue;
|
||||
|
||||
if (g->modMask != MODS)
|
||||
continue;
|
||||
|
||||
m_activeGesture = g;
|
||||
g->currentDirection = g->gesture->isDirectionSensitive() ? g->direction : direction;
|
||||
m_activeGesture->gesture->begin({.pinch = &e, .direction = direction});
|
||||
break;
|
||||
}
|
||||
|
||||
if (!m_activeGesture) {
|
||||
m_gestureFindFailed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_activeGesture->gesture->update({.pinch = &e, .direction = m_activeGesture->currentDirection});
|
||||
}
|
||||
|
||||
void CTrackpadGestures::gestureEnd(const IPointer::SPinchEndEvent& e) {
|
||||
if (!m_activeGesture)
|
||||
return;
|
||||
|
||||
m_activeGesture->gesture->end({.pinch = &e, .direction = m_activeGesture->direction});
|
||||
|
||||
m_activeGesture.reset();
|
||||
}
|
||||
43
src/managers/input/trackpad/TrackpadGestures.hpp
Normal file
43
src/managers/input/trackpad/TrackpadGestures.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../../devices/IPointer.hpp"
|
||||
|
||||
#include "gestures/ITrackpadGesture.hpp"
|
||||
#include "GestureTypes.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <expected>
|
||||
|
||||
class CTrackpadGestures {
|
||||
public:
|
||||
void clearGestures();
|
||||
std::expected<void, std::string> addGesture(UP<ITrackpadGesture>&& gesture, size_t fingerCount, eTrackpadGestureDirection direction, uint32_t modMask, float deltaScale);
|
||||
|
||||
void gestureBegin(const IPointer::SSwipeBeginEvent& e);
|
||||
void gestureUpdate(const IPointer::SSwipeUpdateEvent& e);
|
||||
void gestureEnd(const IPointer::SSwipeEndEvent& e);
|
||||
|
||||
void gestureBegin(const IPointer::SPinchBeginEvent& e);
|
||||
void gestureUpdate(const IPointer::SPinchUpdateEvent& e);
|
||||
void gestureEnd(const IPointer::SPinchEndEvent& e);
|
||||
|
||||
eTrackpadGestureDirection dirForString(const std::string_view& s);
|
||||
const char* stringForDir(eTrackpadGestureDirection dir);
|
||||
|
||||
private:
|
||||
struct SGestureData {
|
||||
UP<ITrackpadGesture> gesture;
|
||||
size_t fingerCount = 0;
|
||||
uint32_t modMask = 0;
|
||||
eTrackpadGestureDirection direction = TRACKPAD_GESTURE_DIR_NONE; // configured dir
|
||||
float deltaScale = 1.F;
|
||||
eTrackpadGestureDirection currentDirection = TRACKPAD_GESTURE_DIR_NONE; // actual dir of that select swipe
|
||||
};
|
||||
|
||||
std::vector<SP<SGestureData>> m_gestures;
|
||||
|
||||
SP<SGestureData> m_activeGesture = nullptr;
|
||||
bool m_gestureFindFailed = false;
|
||||
};
|
||||
|
||||
inline UP<CTrackpadGestures> g_pTrackpadGestures = makeUnique<CTrackpadGestures>();
|
||||
145
src/managers/input/trackpad/gestures/CloseGesture.cpp
Normal file
145
src/managers/input/trackpad/gestures/CloseGesture.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
#include "CloseGesture.hpp"
|
||||
|
||||
#include "../../../../Compositor.hpp"
|
||||
#include "../../../../managers/LayoutManager.hpp"
|
||||
#include "../../../../managers/animation/DesktopAnimationManager.hpp"
|
||||
#include "../../../../render/Renderer.hpp"
|
||||
#include "../../../../managers/eventLoop/EventLoopManager.hpp"
|
||||
#include "../../../../managers/eventLoop/EventLoopTimer.hpp"
|
||||
#include "../../../../config/ConfigValue.hpp"
|
||||
|
||||
constexpr const float MAX_DISTANCE = 200.F;
|
||||
|
||||
static std::vector<SP<CEventLoopTimer>> trackpadCloseTimers;
|
||||
|
||||
//
|
||||
static Vector2D lerpVal(const Vector2D& from, const Vector2D& to, const float& t) {
|
||||
return Vector2D{
|
||||
from.x + ((to.x - from.x) * t),
|
||||
from.y + ((to.y - from.y) * t),
|
||||
};
|
||||
}
|
||||
|
||||
static float lerpVal(const float& from, const float& to, const float& t) {
|
||||
return from + ((to - from) * t);
|
||||
}
|
||||
|
||||
void CCloseTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
||||
ITrackpadGesture::begin(e);
|
||||
|
||||
m_window = g_pCompositor->m_lastWindow;
|
||||
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
m_alphaFrom = m_window->m_alpha->goal();
|
||||
m_posFrom = m_window->m_realPosition->goal();
|
||||
m_sizeFrom = m_window->m_realSize->goal();
|
||||
|
||||
g_pDesktopAnimationManager->startAnimation(m_window.lock(), CDesktopAnimationManager::ANIMATION_TYPE_OUT, true);
|
||||
*m_window->m_alpha = 0.f;
|
||||
|
||||
m_alphaTo = m_window->m_alpha->goal();
|
||||
m_posTo = m_window->m_realPosition->goal();
|
||||
m_sizeTo = m_window->m_realSize->goal();
|
||||
|
||||
m_window->m_alpha->setValueAndWarp(m_alphaFrom);
|
||||
m_window->m_realPosition->setValueAndWarp(m_posFrom);
|
||||
m_window->m_realSize->setValueAndWarp(m_sizeFrom);
|
||||
|
||||
m_lastDelta = 0.F;
|
||||
}
|
||||
|
||||
void CCloseTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
|
||||
m_lastDelta += distance(e);
|
||||
|
||||
const auto FADEPERCENT = std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F);
|
||||
|
||||
m_window->m_alpha->setValueAndWarp(lerpVal(m_alphaFrom, m_alphaTo, FADEPERCENT));
|
||||
m_window->m_realPosition->setValueAndWarp(lerpVal(m_posFrom, m_posTo, FADEPERCENT));
|
||||
m_window->m_realSize->setValueAndWarp(lerpVal(m_sizeFrom, m_sizeTo, FADEPERCENT));
|
||||
|
||||
g_pDecorationPositioner->onWindowUpdate(m_window.lock());
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
}
|
||||
|
||||
void CCloseTrackpadGesture::end(const ITrackpadGesture::STrackpadGestureEnd& e) {
|
||||
static const auto PTIMEOUT = CConfigValue<Hyprlang::INT>("gestures:close_max_timeout");
|
||||
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
const auto COMPLETION = std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F);
|
||||
|
||||
if (COMPLETION < 0.2F) {
|
||||
// revert the animation
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
*m_window->m_alpha = m_alphaFrom;
|
||||
*m_window->m_realPosition = m_posFrom;
|
||||
*m_window->m_realSize = m_sizeFrom;
|
||||
return;
|
||||
}
|
||||
|
||||
// commence. Close the window and restore our current state to avoid a harsh anim
|
||||
const auto CURRENT_ALPHA = m_window->m_alpha->value();
|
||||
const auto CURRENT_POS = m_window->m_realPosition->value();
|
||||
const auto CURRENT_SIZE = m_window->m_realSize->value();
|
||||
|
||||
g_pCompositor->closeWindow(m_window.lock());
|
||||
|
||||
m_window->m_alpha->setValueAndWarp(CURRENT_ALPHA);
|
||||
m_window->m_realPosition->setValueAndWarp(CURRENT_POS);
|
||||
m_window->m_realSize->setValueAndWarp(CURRENT_SIZE);
|
||||
|
||||
// this is a kinda hack, but oh well.
|
||||
m_window->m_realPosition->setCallbackOnBegin(
|
||||
[CURRENT_POS, window = m_window](auto) {
|
||||
if (!window || !window->m_isMapped)
|
||||
return;
|
||||
|
||||
window->m_realPosition->setValueAndWarp(CURRENT_POS);
|
||||
},
|
||||
false);
|
||||
|
||||
m_window->m_realSize->setCallbackOnBegin(
|
||||
[CURRENT_SIZE, window = m_window](auto) {
|
||||
if (!window || !window->m_isMapped)
|
||||
return;
|
||||
|
||||
window->m_realSize->setValueAndWarp(CURRENT_SIZE);
|
||||
},
|
||||
false);
|
||||
|
||||
// we give windows 2s to close. If they don't, pop them back in.
|
||||
auto timer = makeShared<CEventLoopTimer>(
|
||||
std::chrono::milliseconds(*PTIMEOUT),
|
||||
[window = m_window](SP<CEventLoopTimer> self, void* data) {
|
||||
std::erase(trackpadCloseTimers, self);
|
||||
|
||||
// if after 2 seconds the window is still alive and mapped, we revert our changes.
|
||||
if (!window)
|
||||
return;
|
||||
|
||||
window->m_realPosition->setCallbackOnBegin(nullptr);
|
||||
window->m_realSize->setCallbackOnBegin(nullptr);
|
||||
|
||||
if (!window->m_isMapped)
|
||||
return;
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->recalculateWindow(window.lock());
|
||||
g_pCompositor->updateWindowAnimatedDecorationValues(window.lock());
|
||||
window->sendWindowSize(true);
|
||||
*window->m_alpha = 1.F;
|
||||
},
|
||||
nullptr);
|
||||
trackpadCloseTimers.emplace_back(timer);
|
||||
g_pEventLoopManager->addTimer(timer);
|
||||
|
||||
m_window.reset();
|
||||
}
|
||||
23
src/managers/input/trackpad/gestures/CloseGesture.hpp
Normal file
23
src/managers/input/trackpad/gestures/CloseGesture.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITrackpadGesture.hpp"
|
||||
|
||||
#include "../../../../desktop/DesktopTypes.hpp"
|
||||
|
||||
class CCloseTrackpadGesture : public ITrackpadGesture {
|
||||
public:
|
||||
CCloseTrackpadGesture() = default;
|
||||
virtual ~CCloseTrackpadGesture() = default;
|
||||
|
||||
virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
|
||||
virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
|
||||
virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);
|
||||
|
||||
private:
|
||||
PHLWINDOWREF m_window;
|
||||
|
||||
Vector2D m_posFrom, m_posTo, m_sizeFrom, m_sizeTo;
|
||||
float m_alphaFrom = 0.F, m_alphaTo = 0.F;
|
||||
|
||||
float m_lastDelta = 0.F;
|
||||
};
|
||||
22
src/managers/input/trackpad/gestures/DispatcherGesture.cpp
Normal file
22
src/managers/input/trackpad/gestures/DispatcherGesture.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
#include "DispatcherGesture.hpp"
|
||||
|
||||
#include "../../../../managers/KeybindManager.hpp"
|
||||
|
||||
CDispatcherTrackpadGesture::CDispatcherTrackpadGesture(const std::string& dispatcher, const std::string& data) : m_dispatcher(dispatcher), m_data(data) {
|
||||
;
|
||||
}
|
||||
|
||||
void CDispatcherTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
||||
; // intentionally blank
|
||||
}
|
||||
|
||||
void CDispatcherTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
|
||||
; // intentionally blank
|
||||
}
|
||||
|
||||
void CDispatcherTrackpadGesture::end(const ITrackpadGesture::STrackpadGestureEnd& e) {
|
||||
if (!g_pKeybindManager->m_dispatchers.contains(m_dispatcher))
|
||||
return;
|
||||
|
||||
g_pKeybindManager->m_dispatchers.at(m_dispatcher)(m_data);
|
||||
}
|
||||
16
src/managers/input/trackpad/gestures/DispatcherGesture.hpp
Normal file
16
src/managers/input/trackpad/gestures/DispatcherGesture.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITrackpadGesture.hpp"
|
||||
|
||||
class CDispatcherTrackpadGesture : public ITrackpadGesture {
|
||||
public:
|
||||
CDispatcherTrackpadGesture(const std::string& dispatcher, const std::string& data);
|
||||
virtual ~CDispatcherTrackpadGesture() = default;
|
||||
|
||||
virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
|
||||
virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
|
||||
virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);
|
||||
|
||||
private:
|
||||
std::string m_dispatcher, m_data;
|
||||
};
|
||||
88
src/managers/input/trackpad/gestures/FloatGesture.cpp
Normal file
88
src/managers/input/trackpad/gestures/FloatGesture.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include "FloatGesture.hpp"
|
||||
|
||||
#include "../../../../Compositor.hpp"
|
||||
#include "../../../../managers/LayoutManager.hpp"
|
||||
#include "../../../../render/Renderer.hpp"
|
||||
|
||||
constexpr const float MAX_DISTANCE = 250.F;
|
||||
|
||||
//
|
||||
static Vector2D lerpVal(const Vector2D& from, const Vector2D& to, const float& t) {
|
||||
return Vector2D{
|
||||
from.x + ((to.x - from.x) * t),
|
||||
from.y + ((to.y - from.y) * t),
|
||||
};
|
||||
}
|
||||
|
||||
CFloatTrackpadGesture::CFloatTrackpadGesture(const std::string_view& data) {
|
||||
std::string lc = std::string{data};
|
||||
std::ranges::transform(lc, lc.begin(), ::tolower);
|
||||
|
||||
if (lc.starts_with("float"))
|
||||
m_mode = FLOAT_MODE_FLOAT;
|
||||
else if (lc.starts_with("tile"))
|
||||
m_mode == FLOAT_MODE_TILE;
|
||||
else
|
||||
m_mode = FLOAT_MODE_TOGGLE;
|
||||
}
|
||||
|
||||
void CFloatTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
||||
ITrackpadGesture::begin(e);
|
||||
|
||||
m_window = g_pCompositor->m_lastWindow;
|
||||
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
if ((m_window->m_isFloating && m_mode == FLOAT_MODE_FLOAT) || (!m_window->m_isFloating && m_mode == FLOAT_MODE_TILE)) {
|
||||
m_window.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
m_window->m_isFloating = !m_window->m_isFloating;
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(m_window.lock());
|
||||
|
||||
m_posFrom = m_window->m_realPosition->begun();
|
||||
m_sizeFrom = m_window->m_realSize->begun();
|
||||
|
||||
m_posTo = m_window->m_realPosition->goal();
|
||||
m_sizeTo = m_window->m_realSize->goal();
|
||||
|
||||
m_lastDelta = 0.F;
|
||||
}
|
||||
|
||||
void CFloatTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
|
||||
m_lastDelta += distance(e);
|
||||
|
||||
const auto FADEPERCENT = std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F);
|
||||
|
||||
m_window->m_realPosition->setValueAndWarp(lerpVal(m_posFrom, m_posTo, FADEPERCENT));
|
||||
m_window->m_realSize->setValueAndWarp(lerpVal(m_sizeFrom, m_sizeTo, FADEPERCENT));
|
||||
|
||||
g_pDecorationPositioner->onWindowUpdate(m_window.lock());
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
}
|
||||
|
||||
void CFloatTrackpadGesture::end(const ITrackpadGesture::STrackpadGestureEnd& e) {
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
const auto COMPLETION = std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F);
|
||||
|
||||
if (COMPLETION < 0.2F) {
|
||||
// revert the animation
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
m_window->m_isFloating = !m_window->m_isFloating;
|
||||
g_pLayoutManager->getCurrentLayout()->changeWindowFloatingMode(m_window.lock());
|
||||
return;
|
||||
}
|
||||
|
||||
*m_window->m_realPosition = m_posTo;
|
||||
*m_window->m_realSize = m_sizeTo;
|
||||
}
|
||||
30
src/managers/input/trackpad/gestures/FloatGesture.hpp
Normal file
30
src/managers/input/trackpad/gestures/FloatGesture.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITrackpadGesture.hpp"
|
||||
|
||||
#include "../../../../desktop/DesktopTypes.hpp"
|
||||
|
||||
class CFloatTrackpadGesture : public ITrackpadGesture {
|
||||
public:
|
||||
CFloatTrackpadGesture(const std::string_view& mode);
|
||||
virtual ~CFloatTrackpadGesture() = default;
|
||||
|
||||
virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
|
||||
virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
|
||||
virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);
|
||||
|
||||
private:
|
||||
PHLWINDOWREF m_window;
|
||||
|
||||
Vector2D m_posFrom, m_posTo, m_sizeFrom, m_sizeTo;
|
||||
|
||||
float m_lastDelta = 0;
|
||||
|
||||
enum eMode : uint8_t {
|
||||
FLOAT_MODE_TOGGLE = 0,
|
||||
FLOAT_MODE_FLOAT,
|
||||
FLOAT_MODE_TILE,
|
||||
};
|
||||
|
||||
eMode m_mode = FLOAT_MODE_TOGGLE;
|
||||
};
|
||||
97
src/managers/input/trackpad/gestures/FullscreenGesture.cpp
Normal file
97
src/managers/input/trackpad/gestures/FullscreenGesture.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
#include "FullscreenGesture.hpp"
|
||||
|
||||
#include "../../../../Compositor.hpp"
|
||||
#include "../../../../render/Renderer.hpp"
|
||||
#include "../../../animation/DesktopAnimationManager.hpp"
|
||||
|
||||
constexpr const float MAX_DISTANCE = 250.F;
|
||||
|
||||
//
|
||||
static Vector2D lerpVal(const Vector2D& from, const Vector2D& to, const float& t) {
|
||||
return Vector2D{
|
||||
from.x + ((to.x - from.x) * t),
|
||||
from.y + ((to.y - from.y) * t),
|
||||
};
|
||||
}
|
||||
|
||||
CFullscreenTrackpadGesture::CFullscreenTrackpadGesture(const std::string_view& mode) {
|
||||
std::string lc = std::string{mode};
|
||||
std::ranges::transform(lc, lc.begin(), ::tolower);
|
||||
|
||||
if (lc.starts_with("fullscreen"))
|
||||
m_mode = MODE_FULLSCREEN;
|
||||
else if (lc.starts_with("maximize"))
|
||||
m_mode == MODE_MAXIMIZE;
|
||||
else
|
||||
m_mode = MODE_FULLSCREEN;
|
||||
}
|
||||
|
||||
void CFullscreenTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
||||
ITrackpadGesture::begin(e);
|
||||
|
||||
m_window = g_pCompositor->m_lastWindow;
|
||||
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
m_posFrom = m_window->m_realPosition->goal();
|
||||
m_sizeFrom = m_window->m_realSize->goal();
|
||||
|
||||
m_originalMode = m_window->m_fullscreenState.internal;
|
||||
|
||||
g_pCompositor->setWindowFullscreenInternal(m_window.lock(), m_window->m_fullscreenState.internal == FSMODE_NONE ? fsModeForMode(m_mode) : FSMODE_NONE);
|
||||
|
||||
m_posTo = m_window->m_realPosition->goal();
|
||||
m_sizeTo = m_window->m_realSize->goal();
|
||||
|
||||
m_lastDelta = 0.F;
|
||||
}
|
||||
|
||||
void CFullscreenTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
|
||||
m_lastDelta += distance(e);
|
||||
|
||||
const auto FADEPERCENT = std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F);
|
||||
|
||||
m_window->m_realPosition->setValueAndWarp(lerpVal(m_posFrom, m_posTo, FADEPERCENT));
|
||||
m_window->m_realSize->setValueAndWarp(lerpVal(m_sizeFrom, m_sizeTo, FADEPERCENT));
|
||||
|
||||
g_pDesktopAnimationManager->overrideFullscreenFadeAmount(m_window->m_workspace, m_originalMode == FSMODE_NONE ? 1.F - FADEPERCENT : FADEPERCENT, m_window.lock());
|
||||
|
||||
g_pDecorationPositioner->onWindowUpdate(m_window.lock());
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
}
|
||||
|
||||
void CFullscreenTrackpadGesture::end(const ITrackpadGesture::STrackpadGestureEnd& e) {
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
const auto COMPLETION = std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F);
|
||||
|
||||
if (COMPLETION < 0.2F) {
|
||||
// revert the animation
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
m_window->m_isFloating = !m_window->m_isFloating;
|
||||
g_pDesktopAnimationManager->overrideFullscreenFadeAmount(m_window->m_workspace, m_originalMode == FSMODE_NONE ? 1.F : 0.F, m_window.lock());
|
||||
g_pCompositor->setWindowFullscreenInternal(m_window.lock(), m_window->m_fullscreenState.internal == FSMODE_NONE ? m_originalMode : FSMODE_NONE);
|
||||
return;
|
||||
}
|
||||
|
||||
*m_window->m_realPosition = m_posTo;
|
||||
*m_window->m_realSize = m_sizeTo;
|
||||
g_pDesktopAnimationManager->overrideFullscreenFadeAmount(m_window->m_workspace, m_originalMode == FSMODE_NONE ? 0.F : 1.F);
|
||||
}
|
||||
|
||||
eFullscreenMode CFullscreenTrackpadGesture::fsModeForMode(eMode mode) {
|
||||
switch (mode) {
|
||||
case MODE_FULLSCREEN: return FSMODE_FULLSCREEN;
|
||||
case MODE_MAXIMIZE: return FSMODE_MAXIMIZED;
|
||||
default: break;
|
||||
}
|
||||
return FSMODE_FULLSCREEN;
|
||||
}
|
||||
33
src/managers/input/trackpad/gestures/FullscreenGesture.hpp
Normal file
33
src/managers/input/trackpad/gestures/FullscreenGesture.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITrackpadGesture.hpp"
|
||||
|
||||
#include "../../../../desktop/DesktopTypes.hpp"
|
||||
#include "../../../../desktop/Workspace.hpp"
|
||||
|
||||
class CFullscreenTrackpadGesture : public ITrackpadGesture {
|
||||
public:
|
||||
CFullscreenTrackpadGesture(const std::string_view& mode);
|
||||
virtual ~CFullscreenTrackpadGesture() = default;
|
||||
|
||||
virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
|
||||
virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
|
||||
virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);
|
||||
|
||||
private:
|
||||
PHLWINDOWREF m_window;
|
||||
|
||||
Vector2D m_posFrom, m_posTo, m_sizeFrom, m_sizeTo;
|
||||
|
||||
float m_lastDelta = 0;
|
||||
|
||||
enum eMode : uint8_t {
|
||||
MODE_FULLSCREEN = 0,
|
||||
MODE_MAXIMIZE,
|
||||
};
|
||||
|
||||
eMode m_mode = MODE_FULLSCREEN;
|
||||
eFullscreenMode m_originalMode = FSMODE_NONE;
|
||||
|
||||
eFullscreenMode fsModeForMode(eMode mode);
|
||||
};
|
||||
40
src/managers/input/trackpad/gestures/ITrackpadGesture.cpp
Normal file
40
src/managers/input/trackpad/gestures/ITrackpadGesture.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "ITrackpadGesture.hpp"
|
||||
|
||||
// scale the pinch "scale" to match our imaginary delta units
|
||||
constexpr const float PINCH_DELTA_SCALE = 400.F;
|
||||
constexpr const float PINCH_DELTA_SCALE_OUT_ADD = 1.6F;
|
||||
|
||||
//
|
||||
void ITrackpadGesture::begin(const STrackpadGestureBegin& e) {
|
||||
m_lastPinchScale = 1.F;
|
||||
m_scale = e.scale;
|
||||
}
|
||||
|
||||
float ITrackpadGesture::distance(const STrackpadGestureBegin& e) {
|
||||
if (e.direction == TRACKPAD_GESTURE_DIR_LEFT || e.direction == TRACKPAD_GESTURE_DIR_RIGHT || e.direction == TRACKPAD_GESTURE_DIR_HORIZONTAL)
|
||||
return m_scale * (e.direction == TRACKPAD_GESTURE_DIR_LEFT ? -e.swipe->delta.x : e.swipe->delta.x);
|
||||
if (e.direction == TRACKPAD_GESTURE_DIR_UP || e.direction == TRACKPAD_GESTURE_DIR_DOWN || e.direction == TRACKPAD_GESTURE_DIR_VERTICAL)
|
||||
return m_scale * (e.direction == TRACKPAD_GESTURE_DIR_UP ? -e.swipe->delta.y : e.swipe->delta.y);
|
||||
if (e.direction == TRACKPAD_GESTURE_DIR_SWIPE)
|
||||
return m_scale * (e.swipe->delta.size());
|
||||
if (e.direction == TRACKPAD_GESTURE_DIR_PINCH || e.direction == TRACKPAD_GESTURE_DIR_PINCH_IN || e.direction == TRACKPAD_GESTURE_DIR_PINCH_OUT) {
|
||||
const auto Δ = m_lastPinchScale - e.pinch->scale;
|
||||
m_lastPinchScale = e.pinch->scale;
|
||||
return m_scale * ((e.direction == TRACKPAD_GESTURE_DIR_PINCH_IN ? -Δ : Δ * PINCH_DELTA_SCALE_OUT_ADD) * PINCH_DELTA_SCALE);
|
||||
}
|
||||
|
||||
return m_scale * (e.swipe ? e.swipe->delta.size() : e.pinch->delta.size());
|
||||
}
|
||||
|
||||
float ITrackpadGesture::distance(const STrackpadGestureUpdate& e) {
|
||||
return ITrackpadGesture::distance(STrackpadGestureBegin{
|
||||
.swipe = e.swipe,
|
||||
.pinch = e.pinch,
|
||||
.direction = e.direction,
|
||||
.scale = e.scale,
|
||||
});
|
||||
}
|
||||
|
||||
bool ITrackpadGesture::isDirectionSensitive() {
|
||||
return false;
|
||||
}
|
||||
43
src/managers/input/trackpad/gestures/ITrackpadGesture.hpp
Normal file
43
src/managers/input/trackpad/gestures/ITrackpadGesture.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../../../devices/IPointer.hpp"
|
||||
#include "../GestureTypes.hpp"
|
||||
|
||||
class ITrackpadGesture {
|
||||
public:
|
||||
virtual ~ITrackpadGesture() = default;
|
||||
|
||||
struct STrackpadGestureBegin {
|
||||
// this has update because we wait for the delta
|
||||
const IPointer::SSwipeUpdateEvent* swipe = nullptr;
|
||||
const IPointer::SPinchUpdateEvent* pinch = nullptr;
|
||||
eTrackpadGestureDirection direction = TRACKPAD_GESTURE_DIR_NONE;
|
||||
float scale = 1.F;
|
||||
};
|
||||
|
||||
struct STrackpadGestureUpdate {
|
||||
const IPointer::SSwipeUpdateEvent* swipe = nullptr;
|
||||
const IPointer::SPinchUpdateEvent* pinch = nullptr;
|
||||
eTrackpadGestureDirection direction = TRACKPAD_GESTURE_DIR_NONE;
|
||||
float scale = 1.F;
|
||||
};
|
||||
|
||||
struct STrackpadGestureEnd {
|
||||
const IPointer::SSwipeEndEvent* swipe = nullptr;
|
||||
const IPointer::SPinchEndEvent* pinch = nullptr;
|
||||
eTrackpadGestureDirection direction = TRACKPAD_GESTURE_DIR_NONE;
|
||||
float scale = 1.F;
|
||||
};
|
||||
|
||||
virtual void begin(const STrackpadGestureBegin& e);
|
||||
virtual void update(const STrackpadGestureUpdate& e) = 0;
|
||||
virtual void end(const STrackpadGestureEnd& e) = 0;
|
||||
|
||||
virtual float distance(const STrackpadGestureBegin& e);
|
||||
virtual float distance(const STrackpadGestureUpdate& e);
|
||||
|
||||
virtual bool isDirectionSensitive();
|
||||
|
||||
protected:
|
||||
float m_lastPinchScale = 1.F, m_scale = 1.F;
|
||||
};
|
||||
66
src/managers/input/trackpad/gestures/MoveGesture.cpp
Normal file
66
src/managers/input/trackpad/gestures/MoveGesture.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include "MoveGesture.hpp"
|
||||
|
||||
#include "../../../../Compositor.hpp"
|
||||
#include "../../../../managers/LayoutManager.hpp"
|
||||
#include "../../../../render/Renderer.hpp"
|
||||
|
||||
void CMoveTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
||||
ITrackpadGesture::begin(e);
|
||||
|
||||
m_window = g_pCompositor->m_lastWindow;
|
||||
m_lastDelta = {};
|
||||
}
|
||||
|
||||
void CMoveTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
const auto DELTA = e.swipe ? e.swipe->delta : e.pinch->delta;
|
||||
|
||||
if (m_window->m_isFloating) {
|
||||
g_pLayoutManager->getCurrentLayout()->moveActiveWindow(DELTA, m_window.lock());
|
||||
m_window->m_realSize->warp();
|
||||
m_window->m_realPosition->warp();
|
||||
return;
|
||||
}
|
||||
|
||||
// tiled window -> displace, then execute a move dispatcher on end.
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
|
||||
// funny name but works on tiled too lmao
|
||||
m_lastDelta += DELTA;
|
||||
m_window->m_floatingOffset = (m_lastDelta * 0.5F).clamp(Vector2D{-100.F, -100.F}, Vector2D{100.F, 100.F});
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
}
|
||||
|
||||
void CMoveTrackpadGesture::end(const ITrackpadGesture::STrackpadGestureEnd& e) {
|
||||
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
if (m_window->m_isFloating || m_lastDelta.size() < 0.1F)
|
||||
return;
|
||||
|
||||
// tiled: attempt to move window in the given direction
|
||||
|
||||
const auto WINDOWPOS = m_window->m_realPosition->goal() + m_window->m_floatingOffset;
|
||||
|
||||
m_window->m_floatingOffset = {};
|
||||
|
||||
if (std::abs(m_lastDelta.x) > std::abs(m_lastDelta.y)) {
|
||||
// horizontal
|
||||
g_pLayoutManager->getCurrentLayout()->moveWindowTo(m_window.lock(), m_lastDelta.x > 0 ? "r" : "l");
|
||||
} else {
|
||||
// vertical
|
||||
g_pLayoutManager->getCurrentLayout()->moveWindowTo(m_window.lock(), m_lastDelta.y > 0 ? "b" : "t");
|
||||
}
|
||||
|
||||
const auto GOAL = m_window->m_realPosition->goal();
|
||||
|
||||
m_window->m_realPosition->setValueAndWarp(WINDOWPOS);
|
||||
*m_window->m_realPosition = GOAL;
|
||||
|
||||
m_window.reset();
|
||||
}
|
||||
19
src/managers/input/trackpad/gestures/MoveGesture.hpp
Normal file
19
src/managers/input/trackpad/gestures/MoveGesture.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITrackpadGesture.hpp"
|
||||
|
||||
#include "../../../../desktop/DesktopTypes.hpp"
|
||||
|
||||
class CMoveTrackpadGesture : public ITrackpadGesture {
|
||||
public:
|
||||
CMoveTrackpadGesture() = default;
|
||||
virtual ~CMoveTrackpadGesture() = default;
|
||||
|
||||
virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
|
||||
virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
|
||||
virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);
|
||||
|
||||
private:
|
||||
PHLWINDOWREF m_window;
|
||||
Vector2D m_lastDelta;
|
||||
};
|
||||
29
src/managers/input/trackpad/gestures/ResizeGesture.cpp
Normal file
29
src/managers/input/trackpad/gestures/ResizeGesture.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
#include "ResizeGesture.hpp"
|
||||
|
||||
#include "../../../../Compositor.hpp"
|
||||
#include "../../../../managers/LayoutManager.hpp"
|
||||
#include "../../../../render/Renderer.hpp"
|
||||
|
||||
void CResizeTrackpadGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
||||
ITrackpadGesture::begin(e);
|
||||
|
||||
m_window = g_pCompositor->m_lastWindow;
|
||||
}
|
||||
|
||||
void CResizeTrackpadGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
|
||||
if (!m_window)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
|
||||
g_pLayoutManager->getCurrentLayout()->resizeActiveWindow((e.swipe ? e.swipe->delta : e.pinch->delta),
|
||||
cornerFromBox(m_window->getWindowMainSurfaceBox(), g_pInputManager->getMouseCoordsInternal()), m_window.lock());
|
||||
m_window->m_realSize->warp();
|
||||
m_window->m_realPosition->warp();
|
||||
|
||||
g_pHyprRenderer->damageWindow(m_window.lock());
|
||||
}
|
||||
|
||||
void CResizeTrackpadGesture::end(const ITrackpadGesture::STrackpadGestureEnd& e) {
|
||||
m_window.reset();
|
||||
}
|
||||
18
src/managers/input/trackpad/gestures/ResizeGesture.hpp
Normal file
18
src/managers/input/trackpad/gestures/ResizeGesture.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITrackpadGesture.hpp"
|
||||
|
||||
#include "../../../../desktop/DesktopTypes.hpp"
|
||||
|
||||
class CResizeTrackpadGesture : public ITrackpadGesture {
|
||||
public:
|
||||
CResizeTrackpadGesture() = default;
|
||||
virtual ~CResizeTrackpadGesture() = default;
|
||||
|
||||
virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
|
||||
virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
|
||||
virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);
|
||||
|
||||
private:
|
||||
PHLWINDOWREF m_window;
|
||||
};
|
||||
126
src/managers/input/trackpad/gestures/SpecialWorkspaceGesture.cpp
Normal file
126
src/managers/input/trackpad/gestures/SpecialWorkspaceGesture.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
#include "SpecialWorkspaceGesture.hpp"
|
||||
|
||||
#include "../../../../Compositor.hpp"
|
||||
#include "../../../../managers/LayoutManager.hpp"
|
||||
#include "../../../../render/Renderer.hpp"
|
||||
|
||||
#include <hyprutils/memory/Casts.hpp>
|
||||
using namespace Hyprutils::Memory;
|
||||
|
||||
constexpr const float MAX_DISTANCE = 150.F;
|
||||
|
||||
//
|
||||
static Vector2D lerpVal(const Vector2D& from, const Vector2D& to, const float& t) {
|
||||
return Vector2D{
|
||||
from.x + ((to.x - from.x) * t),
|
||||
from.y + ((to.y - from.y) * t),
|
||||
};
|
||||
}
|
||||
|
||||
static float lerpVal(const float& from, const float& to, const float& t) {
|
||||
return from + ((to - from) * t);
|
||||
}
|
||||
|
||||
CSpecialWorkspaceGesture::CSpecialWorkspaceGesture(const std::string& workspaceName) : m_specialWorkspaceName(workspaceName) {
|
||||
;
|
||||
}
|
||||
|
||||
void CSpecialWorkspaceGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
||||
ITrackpadGesture::begin(e);
|
||||
|
||||
m_specialWorkspace.reset();
|
||||
m_lastDelta = 0.F;
|
||||
m_monitor.reset();
|
||||
|
||||
m_specialWorkspace = g_pCompositor->getWorkspaceByName("special:" + m_specialWorkspaceName);
|
||||
|
||||
if (m_specialWorkspace) {
|
||||
m_animatingOut = m_specialWorkspace->isVisible();
|
||||
m_monitor = m_animatingOut ? m_specialWorkspace->m_monitor : g_pCompositor->m_lastMonitor;
|
||||
|
||||
if (!m_monitor)
|
||||
return;
|
||||
|
||||
if (!m_animatingOut)
|
||||
m_monitor->setSpecialWorkspace(m_specialWorkspace);
|
||||
} else {
|
||||
m_monitor = g_pCompositor->m_lastMonitor;
|
||||
|
||||
if (!m_monitor)
|
||||
return;
|
||||
|
||||
m_animatingOut = false;
|
||||
|
||||
const auto& [workspaceID, workspaceName] = getWorkspaceIDNameFromString("special:" + m_specialWorkspaceName);
|
||||
const auto WS = g_pCompositor->createNewWorkspace(workspaceID, m_monitor->m_id, workspaceName);
|
||||
m_monitor->setSpecialWorkspace(WS);
|
||||
m_specialWorkspace = WS;
|
||||
}
|
||||
|
||||
if (!m_specialWorkspace)
|
||||
return;
|
||||
|
||||
m_monitorDimFrom = m_monitor->m_specialFade->begun();
|
||||
m_monitorDimTo = m_monitor->m_specialFade->goal();
|
||||
m_workspaceAlphaFrom = m_specialWorkspace->m_alpha->begun();
|
||||
m_workspaceAlphaTo = m_specialWorkspace->m_alpha->goal();
|
||||
m_workspaceOffsetFrom = m_specialWorkspace->m_renderOffset->begun();
|
||||
m_workspaceOffsetTo = m_specialWorkspace->m_renderOffset->goal();
|
||||
}
|
||||
|
||||
void CSpecialWorkspaceGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
|
||||
if (!m_specialWorkspace || !m_monitor)
|
||||
return;
|
||||
|
||||
g_pHyprRenderer->damageMonitor(m_specialWorkspace->m_monitor.lock());
|
||||
|
||||
m_lastDelta += distance(e);
|
||||
|
||||
const auto FADEPERCENT = m_animatingOut ? 1.F - std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F) : std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F);
|
||||
|
||||
m_monitor->m_specialFade->setValueAndWarp(lerpVal(m_monitorDimFrom, m_monitorDimTo, FADEPERCENT));
|
||||
m_specialWorkspace->m_alpha->setValueAndWarp(lerpVal(m_workspaceAlphaFrom, m_workspaceAlphaTo, FADEPERCENT));
|
||||
m_specialWorkspace->m_renderOffset->setValueAndWarp(lerpVal(m_workspaceOffsetFrom, m_workspaceOffsetTo, FADEPERCENT));
|
||||
}
|
||||
|
||||
void CSpecialWorkspaceGesture::end(const ITrackpadGesture::STrackpadGestureEnd& e) {
|
||||
if (!m_specialWorkspace || !m_monitor)
|
||||
return;
|
||||
|
||||
const auto COMPLETION = std::clamp(m_lastDelta / MAX_DISTANCE, 0.F, 1.F);
|
||||
|
||||
if (COMPLETION < 0.3F) {
|
||||
// cancel the operation, which effectively means just flip the animation direction
|
||||
// also flip goals if animating in
|
||||
m_animatingOut = !m_animatingOut;
|
||||
|
||||
if (m_animatingOut) {
|
||||
m_workspaceOffsetTo = m_workspaceOffsetFrom;
|
||||
m_workspaceAlphaTo = m_workspaceAlphaFrom;
|
||||
m_monitorDimTo = m_monitorDimFrom;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_animatingOut) {
|
||||
const auto CURR_WS_ALPHA = m_specialWorkspace->m_alpha->value();
|
||||
const auto CURR_WS_OFFSET = m_specialWorkspace->m_renderOffset->value();
|
||||
const auto CURR_MON_FADE = m_monitor->m_specialFade->value();
|
||||
|
||||
m_monitor->setSpecialWorkspace(nullptr);
|
||||
|
||||
const auto GOAL_WS_ALPHA = m_specialWorkspace->m_alpha->goal();
|
||||
const auto GOAL_WS_OFFSET = m_specialWorkspace->m_renderOffset->goal();
|
||||
|
||||
m_monitor->m_specialFade->setValueAndWarp(CURR_MON_FADE);
|
||||
m_specialWorkspace->m_alpha->setValueAndWarp(CURR_WS_ALPHA);
|
||||
m_specialWorkspace->m_renderOffset->setValueAndWarp(CURR_WS_OFFSET);
|
||||
|
||||
*m_monitor->m_specialFade = 0.F;
|
||||
*m_specialWorkspace->m_alpha = GOAL_WS_ALPHA;
|
||||
*m_specialWorkspace->m_renderOffset = GOAL_WS_OFFSET;
|
||||
} else {
|
||||
*m_monitor->m_specialFade = m_monitorDimTo;
|
||||
*m_specialWorkspace->m_renderOffset = m_workspaceOffsetTo;
|
||||
*m_specialWorkspace->m_alpha = m_workspaceAlphaTo;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITrackpadGesture.hpp"
|
||||
|
||||
#include "../../../../desktop/DesktopTypes.hpp"
|
||||
|
||||
class CSpecialWorkspaceGesture : public ITrackpadGesture {
|
||||
public:
|
||||
CSpecialWorkspaceGesture(const std::string& workspaceName);
|
||||
virtual ~CSpecialWorkspaceGesture() = default;
|
||||
|
||||
virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
|
||||
virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
|
||||
virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);
|
||||
|
||||
private:
|
||||
std::string m_specialWorkspaceName;
|
||||
PHLWORKSPACE m_specialWorkspace;
|
||||
PHLMONITORREF m_monitor;
|
||||
bool m_animatingOut = false;
|
||||
float m_lastDelta = 0.F;
|
||||
|
||||
// animated properties, kinda sucks
|
||||
float m_monitorDimFrom = 0.F, m_monitorDimTo = 0.F;
|
||||
float m_workspaceAlphaFrom = 0.F, m_workspaceAlphaTo = 0.F;
|
||||
Vector2D m_workspaceOffsetFrom = {}, m_workspaceOffsetTo = {};
|
||||
};
|
||||
@ -0,0 +1,50 @@
|
||||
#include "WorkspaceSwipeGesture.hpp"
|
||||
|
||||
#include "../../../../Compositor.hpp"
|
||||
#include "../../../../managers/input/InputManager.hpp"
|
||||
#include "../../../../render/Renderer.hpp"
|
||||
|
||||
#include "../../UnifiedWorkspaceSwipeGesture.hpp"
|
||||
|
||||
void CWorkspaceSwipeGesture::begin(const ITrackpadGesture::STrackpadGestureBegin& e) {
|
||||
ITrackpadGesture::begin(e);
|
||||
|
||||
static auto PSWIPENEW = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_create_new");
|
||||
|
||||
if (g_pSessionLockManager->isSessionLocked() || g_pUnifiedWorkspaceSwipe->isGestureInProgress())
|
||||
return;
|
||||
|
||||
int onMonitor = 0;
|
||||
for (auto const& w : g_pCompositor->getWorkspaces()) {
|
||||
if (w->m_monitor == g_pCompositor->m_lastMonitor && !g_pCompositor->isWorkspaceSpecial(w->m_id))
|
||||
onMonitor++;
|
||||
}
|
||||
|
||||
if (onMonitor < 2 && !*PSWIPENEW)
|
||||
return; // disallow swiping when there's 1 workspace on a monitor
|
||||
|
||||
g_pUnifiedWorkspaceSwipe->begin();
|
||||
}
|
||||
|
||||
void CWorkspaceSwipeGesture::update(const ITrackpadGesture::STrackpadGestureUpdate& e) {
|
||||
if (!g_pUnifiedWorkspaceSwipe->isGestureInProgress())
|
||||
return;
|
||||
|
||||
const float DELTA = distance(e);
|
||||
|
||||
static auto PSWIPEINVR = CConfigValue<Hyprlang::INT>("gestures:workspace_swipe_invert");
|
||||
|
||||
const double D = g_pUnifiedWorkspaceSwipe->m_delta + (*PSWIPEINVR ? -DELTA : DELTA);
|
||||
g_pUnifiedWorkspaceSwipe->update(D);
|
||||
}
|
||||
|
||||
void CWorkspaceSwipeGesture::end(const ITrackpadGesture::STrackpadGestureEnd& e) {
|
||||
if (!g_pUnifiedWorkspaceSwipe->isGestureInProgress())
|
||||
return;
|
||||
|
||||
g_pUnifiedWorkspaceSwipe->end();
|
||||
}
|
||||
|
||||
bool CWorkspaceSwipeGesture::isDirectionSensitive() {
|
||||
return true;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "ITrackpadGesture.hpp"
|
||||
#include "../../../../desktop/DesktopTypes.hpp"
|
||||
|
||||
class CWorkspaceSwipeGesture : public ITrackpadGesture {
|
||||
public:
|
||||
CWorkspaceSwipeGesture() = default;
|
||||
virtual ~CWorkspaceSwipeGesture() = default;
|
||||
|
||||
virtual void begin(const ITrackpadGesture::STrackpadGestureBegin& e);
|
||||
virtual void update(const ITrackpadGesture::STrackpadGestureUpdate& e);
|
||||
virtual void end(const ITrackpadGesture::STrackpadGestureEnd& e);
|
||||
|
||||
virtual bool isDirectionSensitive();
|
||||
};
|
||||
@ -4,7 +4,7 @@
|
||||
#include "core/Output.hpp"
|
||||
#include "../config/ConfigValue.hpp"
|
||||
#include "../config/ConfigManager.hpp"
|
||||
#include "managers/AnimationManager.hpp"
|
||||
#include "managers/animation/AnimationManager.hpp"
|
||||
#include "../helpers/Monitor.hpp"
|
||||
#include "../helpers/MiscFunctions.hpp"
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
#include "../managers/PointerManager.hpp"
|
||||
#include "../managers/input/InputManager.hpp"
|
||||
#include "../managers/HookSystemManager.hpp"
|
||||
#include "../managers/AnimationManager.hpp"
|
||||
#include "../managers/animation/AnimationManager.hpp"
|
||||
#include "../managers/LayoutManager.hpp"
|
||||
#include "../desktop/Window.hpp"
|
||||
#include "../desktop/LayerSurface.hpp"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user