hyprtoolkit

repository·main·Indexed 42 days ago

https://github.com/hyprwm/hyprtoolkit

A modern, lightweight C++ GUI toolkit designed for building Wayland-native applications. It prioritizes a simple API, smooth animations, and easy system theming over cross-platform compatibility. Key components include CBackend for lifecycle and event management, CWaylandPlatform for Wayland integration, and COpenGLRenderer for hardware-accelerated 2D rendering.

Tokens
5.2K
Snippets
15
Records
24
Agent score
53%

What's inside hyprtoolkit

  1. Overview of hyprtoolkit

    main

    hyprtoolkit is a modern, Wayland-native C++ GUI toolkit designed for creating Wayland GUI applications. It focuses on simplicity, smooth animations, ease of use, and simple system theming.

    Note: hyprtoolkit is not cross-platform and does not aim to include an exhaustive feature set; it is intentionally lightweight and specialized for Wayland.

  2. Build hyprtoolkit from source

    main

    You can build hyprtoolkit using a standard CMake workflow. Ensure you have CMake and a C++ compiler installed. The build process uses the Release configuration and installs to the specified prefix.

    cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build
    cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF`
  3. Configure a Combobox using SComboboxData

    main

    To initialize or configure a Combobox element, use the SComboboxData struct. This struct defines the items available in the list, the currently selected item index, a callback function for when the selection changes, and the element's size.

    Key fields:

    • items: A std::vector<std::string> containing the list of options.
    • currentItem: A size_t representing the index of the currently selected item.
    • onChanged: A callback function std::function<void(CSharedPointer<CComboboxElement>, size_t)> that triggers when a user selects a new item. It provides a pointer to the combobox instance and the new index.
    • size: A CDynamicSize object defining the element's dimensions.
    SComboboxData data;
    data.items = {"Option 1", "Option 2", "Option 3"};
    data.currentItem = 0;
    data.onChanged = [](Hyprutils::Memory::CSharedPointer<CComboboxElement> self, size_t newIndex) {
        // Handle selection change
    };
    data.size = CDynamicSize{CDynamicSize::HT_SIZE_AUTO, CDynamicSize::HT_SIZE_AUTO, {}};
  4. Manage Wayland buffers with CWaylandBuffer

    main

    The CWaylandBuffer class manages Wayland-specific buffers, wrapping an Aquamarine::IBuffer. It is used to handle synchronization and buffer validity during the rendering lifecycle.

    Key features:

    • good(): Returns true if the buffer is valid and usable.
    • m_timeline: A SP<CSyncTimeline> used for synchronization.
    • m_waylandState.buffer: Holds the underlying CCWlBuffer.
    • m_waylandState.syncTimeline: Holds the CCWpLinuxDrmSyncobjTimelineV1 for explicit synchronization.
  5. Implement IWaylandWindow for Wayland-specific windowing

    main

    The IWaylandWindow interface defines the required behavior for windows running on a Wayland compositor within the Hyprtoolkit ecosystem. It extends IToolkitWindow and provides methods for handling Wayland-specific lifecycle events, input, and rendering.

    When implementing this interface, you must provide implementations for core window management tasks such as rendering, scaling, and input handling (mouse and IM).

    class MyWaylandWindow : public IWaylandWindow {
    public:
        Hyprutils::Math::Vector2D pixelSize() override;
        float scale() override;
        void render() override;
        void setCursor(ePointerShape shape) override;
        // ... other virtual methods
    };
  6. Manage texture uploads with STextureData

    main

    To render an image, you must first upload it using uploadTexture. This requires an STextureData object which wraps an asynchronous resource (ASP<Hyprgraphics::IAsyncResource>) and defines how the image should fit the target box via eImageFitMode (e.g., IMAGE_FIT_MODE_STRETCH). The method returns a shared pointer to an IRendererTexture which is then used in renderTexture calls.

    STexturaData textureData = {
        .resource = myAsyncResource,
        .fitMode = IMAGE_FIT_MODE_STRETCH
    };
    
    // Upload and get a handle for rendering
    auto textureHandle = renderer->uploadTexture(textureData);
  7. Acquire a Wayland session lock

    main

    To implement a lock screen or secure session, use aquireSessionLock(). This returns a shared pointer to a CWaylandSessionLockState object, which manages the session lock lifecycle via the ext-session-lock-v1 protocol.

    auto lockState = platform.aquireSessionLock();
    if (lockState) {
        // Handle session lock logic
    }
  8. Configure a Textbox element using STextboxData

    main

    To create or configure a CTextboxElement, you provide an STextboxData structure. This structure defines the visual and behavioral properties of the textbox, including its text content, placeholder, and event handlers.

    Key fields in STextboxData:

    • text: The current string content of the textbox.
    • placeholder: The text displayed when the textbox is empty.
    • onTextEdited: A callback function triggered when the text is modified. It receives a shared pointer to the CTextboxElement and the new std::string content.
    • multiline: Boolean determining if the textbox supports multiple lines (defaults to true).
    • password: Boolean determining if the text should be masked (defaults to false).
    • eyeIcon: Boolean to show/hide an eye icon for toggling password visibility (defaults to false).
    • size: A CDynamicSize object defining the element's dimensions (defaults to HT_SIZE_PERCENT with {1, 1}).
    STextboxData data;
    data.text = "Hello World";
    data.placeholder = "Enter text...";
    data.multiline = false;
    data.password = true;
    data.eyeIcon = true;
    data.onTextEdited = [](auto self, const std::string& newText) {
        // Handle text change
    };
  9. Implement the IToolkitWindow interface

    main

    To create a custom application window using hyprtoolkit, you must implement the IToolkitWindow interface. This interface extends IWindow and provides the necessary hooks for rendering, input handling, and window management.

    Key responsibilities for an implementation include:

    • Rendering: Implement the render() method to draw the window content. You can also use onPreRender() for setup before the main render pass.
    • Input Handling: Implement methods for mouse events (mouseEnter, mouseMove, mouseButton, mouseAxis, mouseLeave), keyboard events (keyboardKey), and focus management (setKeyboardFocus, unfocusKeyboard).
    • Window Management: Implement openPopup to handle the creation of popups/menus and setCursor to manage the pointer shape.
    • Damage & Updates: Use damage(Hyprutils::Math::CRegion&& rg) to mark specific regions for redrawing, damageEntire() to invalidate the whole window, and scheduleFrame() to request a new frame.
    class MyToolkitWindow : public Hyprtoolkit::IToolkitWindow {
    public:
        void render() override {
            // Implementation of drawing logic
        }
    
        Hyprtoolkit::SP<Hyprtoolkit::IWindow> openPopup(const Hyprtoolkit::SWindowCreationData& data) override {
            // Implementation of popup creation
            return nullptr;
        }
    
        void setCursor(Hyprtoolkit::ePointerShape shape) override {
            // Implementation of cursor shape changes
        }
    };
  10. Create a CDropdownHandleElement

    main

    The CDropdownHandleElement is a specialized UI element used to represent the dropdown handle (typically an arrow or icon) within a combobox. It is created using a static factory method.

    To customize the handle, provide an SDropdownHandleData struct:

    • size: A CDynamicSize defining the handle's dimensions (defaults to HT_SIZE_PERCENT with {1, 1}).
    • color: A colorFn function that returns a CHyprColor (defaults to red {1.F, 0.F, 0.F}).
    SDropdownHandleData handleData;
    handleData.color = [] { return CHyprColor{1.F, 1.F, 1.F}; }; // White handle
    
    auto handle = CDropdownHandleElement::create(handleData);
  11. Manage clipboard operations in CWaylandPlatform

    main

    The CWaylandPlatform class provides simple methods to interact with the Wayland clipboard.

    • setClipboard(const std::string& text): Sets the clipboard content to the provided string.
    • readClipboard(): Returns the current content of the clipboard as a std::string.
    // Setting clipboard
    platform.setClipboard("Hello from Hyprtoolkit!");
    
    // Reading clipboard
    std::string text = platform.readClipboard();
  12. Use CBackend to manage application lifecycle and events

    main

    The CBackend class is the central entry point for hyprtoolkit. It implements both IBackend and IEventLoop, providing a unified interface for managing system resources, event loops, and hardware outputs.

    Key capabilities include:

    • Event Loop Management: Control the application lifecycle via enterLoop(), cancelPending(), and destroy().
    • File Descriptor Monitoring: Monitor custom file descriptors using addFd(int fd, ...) and removeFd(int fd).
    • Timers: Schedule asynchronous tasks using addTimer.
    • System Integration: Access system icons via systemIcons(), retrieve color palettes via getPalette(), and manage session locks via aquireSessionLock().
    • Display Management: Retrieve available hardware outputs using getOutputs().
    • Window Creation: Open new windows using openWindow(const SWindowCreationData& data).
    // Conceptual usage of CBackend
    Hyprtoolkit::CBackend backend;
    
    // Add a timer
    backend.addTimer(std::chrono::seconds(5), [](auto self, void* data) {
        // Timer callback
    }, nullptr);
    
    // Monitor a file descriptor
    backend.addFd(fd, []() {
        // Callback when fd is readable
    });
    
    // Start the event loop
    backend.enterLoop();