Skip to content

Commit

Permalink
Merge pull request #192 from horriblename/feature/debug-circles
Browse files Browse the repository at this point in the history
Add circles on touch for debugging
  • Loading branch information
horriblename authored Dec 13, 2024
2 parents 300ae7c + 76188ad commit dc19ccb
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 3 deletions.
3 changes: 3 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
inherit (hyprland.inputs) nixpkgs;
withPkgsFor = fn: nixpkgs.lib.genAttrs (builtins.attrNames hyprland.packages) (system: fn system nixpkgs.legacyPackages.${system});
in {
# for debugging
inherit inputs;

packages = withPkgsFor (system: pkgs: let
hyprgrassPackage = pkgs.callPackage ./nix/default.nix {
inherit (hyprland.packages.${system}) hyprland;
Expand Down
95 changes: 95 additions & 0 deletions src/TouchVisualizer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include "TouchVisualizer.hpp"
#include "src/devices/ITouch.hpp"
#include "src/macros.hpp"
#include "src/render/OpenGL.hpp"
#include "src/render/Renderer.hpp"
#include <cairo/cairo.h>
#include <hyprland/src/Compositor.hpp>
#include <hyprland/src/SharedDefs.hpp>
#include <optional>

CBox boxAroundCenter(Vector2D center, double radius) {
return CBox(center.x - radius, center.y - radius, 2 * radius, 2 * radius);
}

Visualizer::Visualizer() {
const int R = TOUCH_POINT_RADIUS;

this->cairoSurface =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 2 * TOUCH_POINT_RADIUS, 2 * TOUCH_POINT_RADIUS);
auto cairo = cairo_create(cairoSurface);

cairo_arc(cairo, R, R, R, 0, 2 * PI);
cairo_set_source_rgba(cairo, 0.8, 0.8, 0.1, 0.6);
cairo_fill(cairo);

cairo_destroy(cairo);

const unsigned char* data = cairo_image_surface_get_data(this->cairoSurface);

this->texture->allocate();
glBindTexture(GL_TEXTURE_2D, this->texture->m_iTexID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2 * TOUCH_POINT_RADIUS, 2 * TOUCH_POINT_RADIUS, 0, GL_RGBA,
GL_UNSIGNED_BYTE, data);
}

Visualizer::~Visualizer() {
if (this->cairoSurface)
cairo_surface_destroy(this->cairoSurface);
}

void Visualizer::onPreRender() {}

void Visualizer::onRender() {
if (this->finger_positions.size() < 1) {
return;
}

const auto monitor = g_pCompositor->m_pLastMonitor.lock();

// HACK: should not damage monitor, however, I don't understand jackshit
// about damage so here we are.
// If you know how to do damage properly I BEG OF YOU PLEASE ABSOLVE ME
// OF MY SINS
if (this->finger_positions.size()) {
g_pHyprRenderer->damageMonitor(monitor);
}

for (auto& finger : this->finger_positions) {
CBox dmg = boxAroundCenter(finger.second.curr, TOUCH_POINT_RADIUS);
g_pHyprOpenGL->renderTexture(this->texture, &dmg, 1.f, 0, true);
}
}

void Visualizer::onTouchDown(ITouch::SDownEvent ev) {
auto mon = g_pCompositor->m_pLastMonitor.lock();
this->finger_positions.emplace(ev.touchID, FingerPos{ev.pos * mon->vecPixelSize + mon->vecPosition, std::nullopt});
g_pCompositor->scheduleFrameForMonitor(mon);
}

void Visualizer::onTouchUp(ITouch::SUpEvent ev) {
this->damageFinger(ev.touchID);
this->finger_positions.erase(ev.touchID);
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->m_pLastMonitor.lock());
}

void Visualizer::onTouchMotion(ITouch::SMotionEvent ev) {
auto mon = g_pCompositor->m_pLastMonitor.lock();
this->finger_positions[ev.touchID] = {ev.pos * mon->vecPixelSize + mon->vecPosition, std::nullopt};
g_pCompositor->scheduleFrameForMonitor(mon);
}

void Visualizer::damageFinger(int32_t id) {
auto finger = this->finger_positions.at(id);

CBox dm = boxAroundCenter(finger.curr, TOUCH_POINT_RADIUS);
g_pHyprRenderer->damageBox(&dm);

if (finger.last_rendered.has_value()) {
dm = boxAroundCenter(finger.last_rendered.value(), TOUCH_POINT_RADIUS);
g_pHyprRenderer->damageBox(&dm);
}
}
33 changes: 33 additions & 0 deletions src/TouchVisualizer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include "src/devices/ITouch.hpp"
#include "src/render/Texture.hpp"
#include <cairo/cairo.h>
#include <hyprland/src/render/OpenGL.hpp>
#include <hyprland/src/render/Shaders.hpp>
#include <hyprutils/memory/SharedPtr.hpp>
#include <optional>
#include <unordered_map>

struct FingerPos {
Vector2D curr;
std::optional<Vector2D> last_rendered;
};

class Visualizer {
public:
Visualizer();
~Visualizer();
void onPreRender();
void onRender();
void damageFinger(int32_t id);

void onTouchDown(ITouch::SDownEvent);
void onTouchUp(ITouch::SUpEvent);
void onTouchMotion(ITouch::SMotionEvent);

private:
SP<CTexture> texture = makeShared<CTexture>();
cairo_surface_t* cairoSurface;
bool tempDamaged = false;
const int TOUCH_POINT_RADIUS = 30;
std::unordered_map<int32_t, FingerPos> finger_positions;
};
42 changes: 39 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
#include "GestureManager.hpp"
#include "TouchVisualizer.hpp"
#include "globals.hpp"
#include "src/SharedDefs.hpp"
#include "version.hpp"

#include <any>
#include <hyprland/src/Compositor.hpp>
#include <hyprland/src/config/ConfigManager.hpp>
#include <hyprland/src/debug/Log.hpp>
Expand All @@ -11,32 +14,63 @@

#include <hyprlang.hpp>
#include <hyprutils/memory/SharedPtr.hpp>
#include <memory>
#include <string>

const CHyprColor s_pluginColor = {0x61 / 255.0f, 0xAF / 255.0f, 0xEF / 255.0f, 1.0f};

inline std::unique_ptr<Visualizer> g_pVisualizer;

void hkOnTouchDown(void* _, SCallbackInfo& cbinfo, std::any e) {
auto ev = std::any_cast<ITouch::SDownEvent>(e);

static auto const VISUALIZE =
(Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:touch_gestures:debug:visualize_touch")
->getDataStaticPtr();

if (**VISUALIZE)
g_pVisualizer->onTouchDown(ev);
cbinfo.cancelled = g_pGestureManager->onTouchDown(ev);
}

void hkOnTouchUp(void* _, SCallbackInfo& cbinfo, std::any e) {
auto ev = std::any_cast<ITouch::SUpEvent>(e);

static auto const VISUALIZE =
(Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:touch_gestures:debug:visualize_touch")
->getDataStaticPtr();

if (**VISUALIZE)
g_pVisualizer->onTouchUp(ev);
cbinfo.cancelled = g_pGestureManager->onTouchUp(ev);
}

void hkOnTouchMove(void* _, SCallbackInfo& cbinfo, std::any e) {
auto ev = std::any_cast<ITouch::SMotionEvent>(e);

static auto const VISUALIZE =
(Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:touch_gestures:debug:visualize_touch")
->getDataStaticPtr();

if (**VISUALIZE)
g_pVisualizer->onTouchMotion(ev);
cbinfo.cancelled = g_pGestureManager->onTouchMove(ev);
}

static void onPreConfigReload() {
g_pGestureManager->internalBinds.clear();
}

void onRenderStage(eRenderStage stage) {
static auto const VISUALIZE =
(Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, "plugin:touch_gestures:debug:visualize_touch")
->getDataStaticPtr();

if (stage == RENDER_LAST_MOMENT && **VISUALIZE) {
g_pVisualizer->onRender();
}
}

void listInternalBinds(std::string) {
Debug::log(LOG, "[hyprgrass] Listing internal binds:");
for (const auto& bind : g_pGestureManager->internalBinds) {
Expand Down Expand Up @@ -90,8 +124,6 @@ APICALL EXPORT std::string PLUGIN_API_VERSION() {
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
PHANDLE = handle;

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
HyprlandAPI::addConfigValue(PHANDLE, "plugin:touch_gestures:workspace_swipe_fingers",
Hyprlang::CConfigValue((Hyprlang::INT)3));
HyprlandAPI::addConfigValue(PHANDLE, "plugin:touch_gestures:workspace_swipe_edge",
Expand All @@ -108,7 +140,8 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
Hyprlang::CConfigValue((Hyprlang::INT)1));
HyprlandAPI::addConfigValue(PHANDLE, "plugin:touch_gestures:emulate_touchpad_swipe",
Hyprlang::CConfigValue((Hyprlang::INT)0));
#pragma GCC diagnostic pop
HyprlandAPI::addConfigValue(PHANDLE, "plugin:touch_gestures:debug:visualize_touch",
Hyprlang::CConfigValue((Hyprlang::INT)0));

HyprlandAPI::addConfigKeyword(PHANDLE, "hyprgrass-bind", onNewBind, Hyprlang::SHandlerOptions{});
HyprlandAPI::addConfigKeyword(PHANDLE, "hyprgrass-bindm", onNewBind, Hyprlang::SHandlerOptions{});
Expand Down Expand Up @@ -138,10 +171,13 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
static auto P1 = HyprlandAPI::registerCallbackDynamic(PHANDLE, "touchDown", hkOnTouchDown);
static auto P2 = HyprlandAPI::registerCallbackDynamic(PHANDLE, "touchUp", hkOnTouchUp);
static auto P3 = HyprlandAPI::registerCallbackDynamic(PHANDLE, "touchMove", hkOnTouchMove);
static auto P4 = HyprlandAPI::registerCallbackDynamic(
PHANDLE, "render", [](void*, SCallbackInfo, std::any arg) { onRenderStage(std::any_cast<eRenderStage>(arg)); });

HyprlandAPI::reloadConfig();

g_pGestureManager = std::make_unique<GestureManager>();
g_pVisualizer = std::make_unique<Visualizer>();

return {"hyprgrass", "Touchscreen gestures", "horriblename", HYPRGRASS_VERSION};
}
Expand Down
1 change: 1 addition & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ shared_module('hyprgrass',
'main.cpp',
'GestureManager.cpp',
'VecSet.cpp',
'TouchVisualizer.cpp',
cpp_args: ['-DWLR_USE_UNSTABLE'],
link_with: [gestures],
dependencies: [
Expand Down

0 comments on commit dc19ccb

Please sign in to comment.