From ea9ca543f9038eba054ab70574212fc38c04fbf3 Mon Sep 17 00:00:00 2001 From: Almamu Date: Fri, 8 Nov 2024 03:07:42 +0100 Subject: [PATCH] feat: support basic single-mouse-click and release events for web backgrounds --- src/WallpaperEngine/Input/CMouseInput.h | 17 +++++++++ .../Input/Drivers/CGLFWMouseInput.cpp | 35 +++++++++++++++++++ .../Input/Drivers/CGLFWMouseInput.h | 12 +++++++ .../Input/Drivers/CWaylandMouseInput.cpp | 35 +++++++++++++++++-- .../Input/Drivers/CWaylandMouseInput.h | 12 ++++++- .../Render/Drivers/CWaylandOpenGLDriver.cpp | 23 +++++++++++- .../Drivers/Output/CWaylandOutputViewport.h | 3 ++ .../Render/Wallpapers/CWeb.cpp | 15 +++++++- 8 files changed, 147 insertions(+), 5 deletions(-) diff --git a/src/WallpaperEngine/Input/CMouseInput.h b/src/WallpaperEngine/Input/CMouseInput.h index ab35e95..9aee5fe 100644 --- a/src/WallpaperEngine/Input/CMouseInput.h +++ b/src/WallpaperEngine/Input/CMouseInput.h @@ -3,6 +3,12 @@ #include namespace WallpaperEngine::Input { +enum MouseClickStatus : int { + Waiting = 0, + Released = 1, + Clicked = 2 +}; + /** * Handles mouse input for the background */ @@ -18,5 +24,16 @@ class CMouseInput { * The virtual pointer's position */ [[nodiscard]] virtual glm::dvec2 position () const = 0; + + /** + * @return The status of the mouse's left click + */ + [[nodiscard]] virtual MouseClickStatus leftClick () const = 0; + + /** + * @return The status of the mouse's right click + */ + [[nodiscard]] virtual MouseClickStatus rightClick () const = 0; + }; } // namespace WallpaperEngine::Input diff --git a/src/WallpaperEngine/Input/Drivers/CGLFWMouseInput.cpp b/src/WallpaperEngine/Input/Drivers/CGLFWMouseInput.cpp index edc5856..6a1f5b6 100644 --- a/src/WallpaperEngine/Input/Drivers/CGLFWMouseInput.cpp +++ b/src/WallpaperEngine/Input/Drivers/CGLFWMouseInput.cpp @@ -16,6 +16,33 @@ void CGLFWMouseInput::update () { return; } + int leftClickState = glfwGetMouseButton (this->m_driver->getWindow (), GLFW_MOUSE_BUTTON_LEFT); + int rightClickState = glfwGetMouseButton (this->m_driver->getWindow (), GLFW_MOUSE_BUTTON_RIGHT); + + if (leftClickState == GLFW_RELEASE) { + if (this->m_leftClick == MouseClickStatus::Released) { + this->m_leftClick = MouseClickStatus::Waiting; + } + + if (this->m_leftClick == MouseClickStatus::Clicked) { + this->m_leftClick = MouseClickStatus::Released; + } + } else { + this->m_leftClick = MouseClickStatus::Clicked; + } + + if (rightClickState == GLFW_RELEASE) { + if (this->m_rightClick == MouseClickStatus::Released) { + this->m_rightClick = MouseClickStatus::Waiting; + } + + if (this->m_rightClick == MouseClickStatus::Clicked) { + this->m_rightClick = MouseClickStatus::Released; + } + } else { + this->m_rightClick = MouseClickStatus::Clicked; + } + // update current mouse position glfwGetCursorPos (this->m_driver->getWindow (), &this->m_mousePosition.x, &this->m_mousePosition.y); // interpolate to the new position @@ -24,4 +51,12 @@ void CGLFWMouseInput::update () { glm::dvec2 CGLFWMouseInput::position () const { return this->m_reportedPosition; +} + +WallpaperEngine::Input::MouseClickStatus CGLFWMouseInput::leftClick () const { + return m_leftClick; +} + +WallpaperEngine::Input::MouseClickStatus CGLFWMouseInput::rightClick () const { + return m_rightClick; } \ No newline at end of file diff --git a/src/WallpaperEngine/Input/Drivers/CGLFWMouseInput.h b/src/WallpaperEngine/Input/Drivers/CGLFWMouseInput.h index e33b762..d6cf235 100644 --- a/src/WallpaperEngine/Input/Drivers/CGLFWMouseInput.h +++ b/src/WallpaperEngine/Input/Drivers/CGLFWMouseInput.h @@ -26,6 +26,16 @@ class CGLFWMouseInput final : public CMouseInput { */ [[nodiscard]] glm::dvec2 position () const override; + /** + * @return The status of the mouse's left click + */ + [[nodiscard]] MouseClickStatus leftClick () const override; + + /** + * @return The status of the mouse's right click + */ + [[nodiscard]] MouseClickStatus rightClick () const override; + private: Render::Drivers::CGLFWOpenGLDriver* m_driver; @@ -34,5 +44,7 @@ class CGLFWMouseInput final : public CMouseInput { */ glm::dvec2 m_mousePosition; glm::dvec2 m_reportedPosition; + MouseClickStatus m_leftClick; + MouseClickStatus m_rightClick; }; } // namespace WallpaperEngine::Input::Drivers diff --git a/src/WallpaperEngine/Input/Drivers/CWaylandMouseInput.cpp b/src/WallpaperEngine/Input/Drivers/CWaylandMouseInput.cpp index eb77fee..06fe635 100644 --- a/src/WallpaperEngine/Input/Drivers/CWaylandMouseInput.cpp +++ b/src/WallpaperEngine/Input/Drivers/CWaylandMouseInput.cpp @@ -5,9 +5,26 @@ using namespace WallpaperEngine::Input::Drivers; CWaylandMouseInput::CWaylandMouseInput (WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver* driver) : waylandDriver (driver), - pos () {} + m_pos () {} -void CWaylandMouseInput::update () {} +void CWaylandMouseInput::update () { + if (!this->waylandDriver->getApp ().getContext ().settings.mouse.enabled) { + return; + } + + if (!waylandDriver->viewportInFocus || !waylandDriver->viewportInFocus->rendering) { + return; + } + + // TODO: IS CLEARING STATE HERE A GOOD SOLUTION? OR SHOULD BE HANDLED SOMEWHERE ELSE? + if (waylandDriver->viewportInFocus->leftClick == MouseClickStatus::Released) { + waylandDriver->viewportInFocus->leftClick = MouseClickStatus::Waiting; + } + + if (waylandDriver->viewportInFocus->rightClick == MouseClickStatus::Released) { + waylandDriver->viewportInFocus->rightClick = MouseClickStatus::Waiting; + } +} glm::dvec2 CWaylandMouseInput::position () const { if (!this->waylandDriver->getApp ().getContext ().settings.mouse.enabled) { @@ -18,4 +35,18 @@ glm::dvec2 CWaylandMouseInput::position () const { return waylandDriver->viewportInFocus->mousePos; return {0, 0}; +} + +WallpaperEngine::Input::MouseClickStatus CWaylandMouseInput::leftClick () const { + if (waylandDriver->viewportInFocus && waylandDriver->viewportInFocus->rendering) + return waylandDriver->viewportInFocus->leftClick; + + return MouseClickStatus::Waiting; +} + +WallpaperEngine::Input::MouseClickStatus CWaylandMouseInput::rightClick () const { + if (waylandDriver->viewportInFocus && waylandDriver->viewportInFocus->rendering) + return waylandDriver->viewportInFocus->rightClick; + + return MouseClickStatus::Waiting; } \ No newline at end of file diff --git a/src/WallpaperEngine/Input/Drivers/CWaylandMouseInput.h b/src/WallpaperEngine/Input/Drivers/CWaylandMouseInput.h index 6e4e446..4f4a298 100644 --- a/src/WallpaperEngine/Input/Drivers/CWaylandMouseInput.h +++ b/src/WallpaperEngine/Input/Drivers/CWaylandMouseInput.h @@ -26,13 +26,23 @@ class CWaylandMouseInput final : public CMouseInput { */ [[nodiscard]] glm::dvec2 position () const override; + /** + * @return The status of the mouse's left click + */ + [[nodiscard]] MouseClickStatus leftClick () const override; + + /** + * @return The status of the mouse's right click + */ + [[nodiscard]] MouseClickStatus rightClick () const override; + private: /** * Wayland: Driver */ WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver* waylandDriver = nullptr; - glm::dvec2 pos; + glm::dvec2 m_pos; }; } // namespace WallpaperEngine::Input::Drivers diff --git a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp index a935c00..80dc9bf 100644 --- a/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp +++ b/src/WallpaperEngine/Render/Drivers/CWaylandOpenGLDriver.cpp @@ -50,7 +50,28 @@ static void handlePointerMotion (void* data, struct wl_pointer* wl_pointer, uint } static void handlePointerButton (void* data, struct wl_pointer* wl_pointer, uint32_t serial, uint32_t time, - uint32_t button, uint32_t button_state) {} + uint32_t button, uint32_t button_state) { + const auto driver = static_cast (data); + + if (!driver->viewportInFocus) + return; + + sLog.debug("Button", button, " state ", button_state); + + if (button == 272) { + if (button_state == WL_POINTER_BUTTON_STATE_PRESSED) { + driver->viewportInFocus->leftClick = WallpaperEngine::Input::MouseClickStatus::Clicked; + } else if (button_state == WL_POINTER_BUTTON_STATE_RELEASED) { + driver->viewportInFocus->leftClick = WallpaperEngine::Input::MouseClickStatus::Released; + } + } else if (button == 273) { + if (button_state == WL_POINTER_BUTTON_STATE_PRESSED) { + driver->viewportInFocus->rightClick = WallpaperEngine::Input::MouseClickStatus::Clicked; + } else if (button_state == WL_POINTER_BUTTON_STATE_RELEASED) { + driver->viewportInFocus->rightClick = WallpaperEngine::Input::MouseClickStatus::Released; + } + } +} constexpr struct wl_pointer_listener pointerListener = {.enter = handlePointerEnter, .leave = handlePointerLeave, diff --git a/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutputViewport.h b/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutputViewport.h index 3ba17df..afb14c6 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutputViewport.h +++ b/src/WallpaperEngine/Render/Drivers/Output/CWaylandOutputViewport.h @@ -10,6 +10,7 @@ #include #include "../CWaylandOpenGLDriver.h" +#include #include "COutputViewport.h" #include @@ -44,6 +45,8 @@ class CWaylandOutputViewport final : public COutputViewport { zwlr_layer_surface_v1* layerSurface = nullptr; wl_callback* frameCallback = nullptr; glm::dvec2 mousePos = {0, 0}; + WallpaperEngine::Input::MouseClickStatus leftClick = WallpaperEngine::Input::MouseClickStatus::Waiting; + WallpaperEngine::Input::MouseClickStatus rightClick = WallpaperEngine::Input::MouseClickStatus::Waiting; wl_cursor* pointer = nullptr; wl_surface* cursorSurface = nullptr; bool callbackInitialized = false; diff --git a/src/WallpaperEngine/Render/Wallpapers/CWeb.cpp b/src/WallpaperEngine/Render/Wallpapers/CWeb.cpp index 971b2b8..4a342d6 100644 --- a/src/WallpaperEngine/Render/Wallpapers/CWeb.cpp +++ b/src/WallpaperEngine/Render/Wallpapers/CWeb.cpp @@ -79,7 +79,11 @@ void CWeb::renderFrame (glm::ivec4 viewport) { void CWeb::updateMouse (glm::ivec4 viewport) { // update virtual mouse position first - glm::dvec2 position = this->getContext ().getInputContext ().getMouseInput ().position (); + auto& input = this->getContext ().getInputContext ().getMouseInput (); + + glm::dvec2 position = input.position (); + WallpaperEngine::Input::MouseClickStatus leftClick = input.leftClick(); + WallpaperEngine::Input::MouseClickStatus rightClick = input.rightClick(); CefMouseEvent evt; // Set mouse current position. Maybe clamps are not needed @@ -87,6 +91,15 @@ void CWeb::updateMouse (glm::ivec4 viewport) { evt.y = std::clamp (int (position.y - viewport.y), 0, viewport.w); // Send mouse position to cef m_browser->GetHost ()->SendMouseMoveEvent (evt, false); + + // TODO: ANY OTHER MOUSE EVENTS TO SEND? + if (leftClick != WallpaperEngine::Input::MouseClickStatus::Waiting) { + m_browser->GetHost ()->SendMouseClickEvent (evt, CefBrowserHost::MouseButtonType::MBT_LEFT, leftClick == WallpaperEngine::Input::MouseClickStatus::Released, 1); + } + + if (rightClick != WallpaperEngine::Input::MouseClickStatus::Waiting) { + m_browser->GetHost ()->SendMouseClickEvent (evt, CefBrowserHost::MouseButtonType::MBT_RIGHT, rightClick == WallpaperEngine::Input::MouseClickStatus::Released, 1); + } } CWeb::~CWeb () {