Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ if (NOT DISABLE_TESTS)
target_link_libraries(controls PRIVATE PkgConfig::deps hyprtoolkit)
add_dependencies(tests controls)

add_executable(simpleSessionLock "tests/SimpleSessionLock.cpp")
target_link_libraries(simpleSessionLock PRIVATE PkgConfig::deps hyprtoolkit)
add_dependencies(tests simpleSessionLock)


# GTest
find_package(GTest CONFIG REQUIRED)
include(GoogleTest)
Expand Down Expand Up @@ -160,6 +165,7 @@ protocolnew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
protocolnew("staging/fractional-scale" "fractional-scale-v1" false)
protocolnew("stable/viewporter" "viewporter" false)
protocolnew("staging/cursor-shape" "cursor-shape-v1" false)
protocolnew("staging/ext-session-lock" "ext-session-lock-v1" false)
protocolnew("stable/tablet" "tablet-v2" false)
protocolnew("unstable/text-input" "text-input-unstable-v3" false)
protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
Expand Down
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,18 @@
inherit (pkgsFor.${system}) hyprtoolkit hyprtoolkit-with-tests;
});

devShells = eachSystem (system: {
default =
pkgsFor.${system}.mkShell.override {
inherit (self.packages.${system}.default) stdenv;
} {
name = "hyprtoolkit-shell";
hardeningDisable = ["fortify"];
inputsFrom = [pkgsFor.${system}.hyprtoolkit];
packages = [pkgsFor.${system}.clang-tools];
};
});

checks = eachSystem (system: self.packages.${system});

formatter = eachSystem (system: pkgsFor.${system}.alejandra);
Expand Down
22 changes: 22 additions & 0 deletions include/hyprtoolkit/core/Backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,19 @@
#include <aquamarine/backend/Null.hpp>
#include <aquamarine/backend/Backend.hpp>
#include <functional>
#include <expected>
#include <string>
#include <sys/poll.h>

#include "LogTypes.hpp"
#include "SessionLock.hpp"
#include "../palette/Palette.hpp"

#include "CoreMacros.hpp"

namespace Hyprtoolkit {
class IWindow;
class IOutput;
class CTimer;
class ISystemIconFactory;
struct SWindowCreationData;
Expand Down Expand Up @@ -73,6 +76,25 @@ namespace Hyprtoolkit {

virtual Hyprutils::Memory::CSharedPointer<CPalette> getPalette() = 0;

/*
Get currently registered outputs.
Make sure you register the `removed` event to get rid of your reference once the output is removed.
*/
virtual std::vector<Hyprutils::Memory::CSharedPointer<IOutput>> getOutputs() = 0;

/*
Create and lock the graphical session.
It is required to call this before HT_WINDOW_LOCK_SURFACE can be used.
*/
virtual std::expected<Hyprutils::Memory::CSharedPointer<ISessionLockState>, eSessionLockError> aquireSessionLock() = 0;

struct {
/*
Get notified when a new output was added.
*/
Hyprutils::Signal::CSignalT<Hyprutils::Memory::CSharedPointer<IOutput>> outputAdded;
} m_events;

protected:
IBackend();
};
Expand Down
20 changes: 20 additions & 0 deletions include/hyprtoolkit/core/Output.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <hyprutils/signal/Signal.hpp>
#include <hyprutils/math/Vector2D.hpp>

namespace Hyprtoolkit {
class IOutput {
public:
virtual ~IOutput() = default;
virtual uint32_t handle() = 0;
virtual std::string port() = 0;
virtual std::string desc() = 0;
virtual uint32_t fps() = 0;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is fps a uint32_t? shouldn't this be a) refresh() and b) refresh... in what? mHz I assume if uint32_t?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh wait I forgot that.

I still wanted to ask you about this.
I only need that to make the animation manager tick in sync with the refresh rate.
Is that the way we should do that?

Copy link
Member

@vaxerski vaxerski Nov 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, tick on a .frame and throttle to max fps (cases with multiple surfaces)

might wanna add that "tick()" to the wl callback in IWaylandWindow


struct {
/* output removed */
Hyprutils::Signal::CSignalT<> removed;
} m_events;
};
}
22 changes: 22 additions & 0 deletions include/hyprtoolkit/core/SessionLock.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <hyprutils/signal/Signal.hpp>
#include <hyprutils/math/Vector2D.hpp>

namespace Hyprtoolkit {
enum eSessionLockError : uint8_t {
PLATFORM_UNINTIALIZED,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LOCK_ERROR_PLATFORM_UNINITIALIZED, etc.

DENIED,
};

class ISessionLockState {
public:
virtual ~ISessionLockState() = default;
virtual void unlock() = 0;

struct {
/* signals that we don't need to unlock anymore. It makes sense to exit upon recieving this */
Hyprutils::Signal::CSignalT<> finished;
} m_events;
};
}
10 changes: 7 additions & 3 deletions include/hyprtoolkit/window/Window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
namespace Hyprtoolkit {
class IElement;
class IWindow;
class IOutput;
struct SWindowCreationData;

enum eWindowType : uint8_t {
HT_WINDOW_TOPLEVEL = 0,
HT_WINDOW_POPUP = 1,
HT_WINDOW_LAYER = 2,
HT_WINDOW_TOPLEVEL = 0,
HT_WINDOW_POPUP = 1,
HT_WINDOW_LAYER = 2,
HT_WINDOW_LOCK_SURFACE = 3,
};

class CWindowBuilder {
Expand All @@ -28,6 +30,8 @@ namespace Hyprtoolkit {
Hyprutils::Memory::CSharedPointer<CWindowBuilder> preferredSize(const Hyprutils::Math::Vector2D&);
Hyprutils::Memory::CSharedPointer<CWindowBuilder> minSize(const Hyprutils::Math::Vector2D&);
Hyprutils::Memory::CSharedPointer<CWindowBuilder> maxSize(const Hyprutils::Math::Vector2D&);
// TODO: implement for window types other than HT_WINDOW_LOCK_SURFACE
Hyprutils::Memory::CSharedPointer<CWindowBuilder> prefferedOutput(const Hyprutils::Memory::CSharedPointer<IOutput>& output);

// only for HT_WINDOW_LAYER
Hyprutils::Memory::CSharedPointer<CWindowBuilder> marginTopLeft(const Hyprutils::Math::Vector2D&);
Expand Down
53 changes: 45 additions & 8 deletions src/core/Backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@

#include "./platforms/WaylandPlatform.hpp"
#include "../renderer/gl/OpenGL.hpp"
#include "../window/WaylandWindow.hpp"
#include "../output/WaylandOutput.hpp"
#include "../window/WaylandLayer.hpp"
#include "../window/WaylandLockSurface.hpp"
#include "../window/WaylandWindow.hpp"
#include "../Macros.hpp"
#include "../element/Element.hpp"
#include "../palette/ConfigManager.hpp"
#include "../system/Icons.hpp"
#include "../sessionLock/WaylandSessionLock.hpp"

#include <sys/wait.h>
#include <sys/poll.h>
Expand Down Expand Up @@ -74,6 +77,13 @@ SP<IBackend> IBackend::create() {
g_logger->log(HT_LOG_ERROR, "couldn't start aq backend");
return nullptr;
}
g_waylandPlatform = makeUnique<CWaylandPlatform>();
if (!g_waylandPlatform->attempt()) {
g_waylandPlatform = nullptr;
return nullptr;
}
g_openGL = makeShared<COpenGLRenderer>(g_waylandPlatform->m_drmState.fd);
g_renderer = g_openGL;

return g_backend;
};
Expand All @@ -90,14 +100,27 @@ SP<CPalette> CBackend::getPalette() {
return g_palette;
}

std::vector<SP<IOutput>> CBackend::getOutputs() {
if (!g_waylandPlatform)
return {};

return std::vector<SP<IOutput>>(g_waylandPlatform->m_outputs.begin(), g_waylandPlatform->m_outputs.end());
}

std::expected<SP<ISessionLockState>, eSessionLockError> CBackend::aquireSessionLock() {
if (!g_waylandPlatform)
return std::unexpected(PLATFORM_UNINTIALIZED);

auto lockState = g_waylandPlatform->aquireSessionLock();
if (!lockState || lockState->m_denied)
return std::unexpected(DENIED);

return lockState;
}

SP<IWindow> CBackend::openWindow(const SWindowCreationData& data) {
if (!g_waylandPlatform) {
g_waylandPlatform = makeUnique<CWaylandPlatform>();
if (!g_waylandPlatform->attempt())
return nullptr;
g_openGL = makeShared<COpenGLRenderer>(g_waylandPlatform->m_drmState.fd);
g_renderer = g_openGL;
}
if (!g_waylandPlatform)
return nullptr;

if (data.type == HT_WINDOW_LAYER) {
if (!g_waylandPlatform->m_waylandState.layerShell)
Expand All @@ -108,6 +131,20 @@ SP<IWindow> CBackend::openWindow(const SWindowCreationData& data) {
w->m_rootElement->impl->window = w;
g_waylandPlatform->m_layers.emplace_back(w);
return w;
} else if (data.type == HT_WINDOW_LOCK_SURFACE) {
if (!g_waylandPlatform->m_waylandState.sessionLock) {
g_logger->log(HT_LOG_ERROR, "No session lock manager. Does your compositor support it?");
return nullptr;
}

if (!g_waylandPlatform->m_sessionLockState || g_waylandPlatform->m_sessionLockState->m_denied || g_waylandPlatform->m_sessionLockState->m_sessionUnlocked)
return nullptr;

auto w = makeShared<CWaylandLockSurface>(data);
w->m_self = w;
w->m_rootElement->impl->window = w;
g_waylandPlatform->m_sessionLockState->m_lockSurfaces.emplace_back(w);
return w;
}

auto w = makeShared<CWaylandWindow>(data);
Expand Down
10 changes: 6 additions & 4 deletions src/core/Backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@ namespace Hyprtoolkit {
virtual void addFd(int fd, std::function<void()>&& callback);
virtual void removeFd(int fd);
virtual SP<ISystemIconFactory> systemIcons();
virtual ASP<CTimer> addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(ASP<CTimer> self, void* data)> cb_, void* data, bool force = false);
virtual void addIdle(const std::function<void()>& fn);
virtual void enterLoop();
virtual SP<CPalette> getPalette();
virtual ASP<CTimer> addTimer(const std::chrono::system_clock::duration& timeout, std::function<void(ASP<CTimer> self, void* data)> cb_, void* data, bool force = false);
virtual void addIdle(const std::function<void()>& fn);
virtual void enterLoop();
virtual std::vector<SP<IOutput>> getOutputs();
virtual SP<CPalette> getPalette();
virtual std::expected<SP<ISessionLockState>, eSessionLockError> aquireSessionLock();

// ======================= Internal fns ======================= //

Expand Down
Loading