瀏覽代碼

feat: support basic single-mouse-click and release events for web backgrounds

Almamu 1 年之前
父節點
當前提交
ea9ca543f9

+ 17 - 0
src/WallpaperEngine/Input/CMouseInput.h

@@ -3,6 +3,12 @@
 #include <glm/vec2.hpp>
 
 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

+ 35 - 0
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;
 }

+ 12 - 0
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

+ 33 - 2
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;
 }

+ 11 - 1
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
 

+ 22 - 1
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<CWaylandOpenGLDriver*> (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,

+ 3 - 0
src/WallpaperEngine/Render/Drivers/Output/CWaylandOutputViewport.h

@@ -10,6 +10,7 @@
 #include <wayland-egl.h>
 
 #include "../CWaylandOpenGLDriver.h"
+#include <WallpaperEngine/Input/CMouseInput.h>
 #include "COutputViewport.h"
 #include <glm/vec2.hpp>
 
@@ -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;

+ 14 - 1
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 () {