mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
Mouse handling
This commit is contained in:
parent
1f6cc8206f
commit
75bb8cc156
@ -12,9 +12,8 @@ CInputContext::CInputContext (CX11OpenGLDriver& videoDriver) :
|
|||||||
|
|
||||||
#ifdef ENABLE_WAYLAND
|
#ifdef ENABLE_WAYLAND
|
||||||
CInputContext::CInputContext (CWaylandOpenGLDriver& videoDriver) :
|
CInputContext::CInputContext (CWaylandOpenGLDriver& videoDriver) :
|
||||||
m_mouse (nullptr)
|
m_mouse (&videoDriver)
|
||||||
{
|
{
|
||||||
// todo
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -5,11 +5,21 @@ using namespace WallpaperEngine::Input;
|
|||||||
|
|
||||||
CMouseInput::CMouseInput (GLFWwindow* window) : position (), m_mousePosition (), m_window (window) {}
|
CMouseInput::CMouseInput (GLFWwindow* window) : position (), m_mousePosition (), m_window (window) {}
|
||||||
|
|
||||||
|
CMouseInput::CMouseInput(WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver* driver) {
|
||||||
|
waylandDriver = driver;
|
||||||
|
}
|
||||||
|
|
||||||
void CMouseInput::update ()
|
void CMouseInput::update ()
|
||||||
{
|
{
|
||||||
if (!m_window)
|
if (!m_window) {
|
||||||
|
if (!waylandDriver || !waylandDriver->lastLSInFocus)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this->position = waylandDriver->lastLSInFocus->mousePos;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// update current mouse position
|
// update current mouse position
|
||||||
glfwGetCursorPos (this->m_window, &this->m_mousePosition.x, &this->m_mousePosition.y);
|
glfwGetCursorPos (this->m_window, &this->m_mousePosition.x, &this->m_mousePosition.y);
|
||||||
// interpolate to the new position
|
// interpolate to the new position
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Render/Drivers/CWaylandOpenGLDriver.h"
|
||||||
|
|
||||||
#include <glm/vec2.hpp>
|
#include <glm/vec2.hpp>
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
|
|
||||||
namespace WallpaperEngine::Input
|
namespace WallpaperEngine::Input
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -13,6 +16,9 @@ namespace WallpaperEngine::Input
|
|||||||
public:
|
public:
|
||||||
explicit CMouseInput(GLFWwindow* window);
|
explicit CMouseInput(GLFWwindow* window);
|
||||||
|
|
||||||
|
explicit CMouseInput(WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver* driver);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes current mouse position and updates it
|
* Takes current mouse position and updates it
|
||||||
*/
|
*/
|
||||||
@ -27,12 +33,17 @@ namespace WallpaperEngine::Input
|
|||||||
/**
|
/**
|
||||||
* The GLFW window to get mouse position from
|
* The GLFW window to get mouse position from
|
||||||
*/
|
*/
|
||||||
GLFWwindow* m_window;
|
GLFWwindow* m_window = nullptr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current mouse position
|
* The current mouse position
|
||||||
*/
|
*/
|
||||||
glm::dvec2 m_mousePosition;
|
glm::dvec2 m_mousePosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wayland: Driver
|
||||||
|
*/
|
||||||
|
WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver* waylandDriver = nullptr;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,12 +20,54 @@ extern "C" {
|
|||||||
|
|
||||||
using namespace WallpaperEngine::Render::Drivers;
|
using namespace WallpaperEngine::Render::Drivers;
|
||||||
|
|
||||||
void geometry(void* data, wl_output* output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char* make, const char* model,
|
static void handlePointerEnter(void* data, struct wl_pointer* wl_pointer, uint32_t serial, struct wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
||||||
|
const auto PDRIVER = (CWaylandOpenGLDriver*)data;
|
||||||
|
const auto PLS = PDRIVER->surfaceToLS(surface);
|
||||||
|
PDRIVER->lastLSInFocus = PLS;
|
||||||
|
wl_surface_set_buffer_scale(PLS->cursorSurface, PLS->output->scale);
|
||||||
|
wl_surface_attach(PLS->cursorSurface, wl_cursor_image_get_buffer(PLS->pointer->images[0]), 0, 0);
|
||||||
|
wl_pointer_set_cursor(wl_pointer, serial, PLS->cursorSurface, PLS->pointer->images[0]->hotspot_x, PLS->pointer->images[0]->hotspot_y);
|
||||||
|
wl_surface_commit(PLS->cursorSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handlePointerLeave(void* data, struct wl_pointer* wl_pointer, uint32_t serial, struct wl_surface* surface) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handlePointerAxis(void* data, wl_pointer* wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handlePointerMotion(void* data, struct wl_pointer* wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
||||||
|
auto x = wl_fixed_to_double(surface_x);
|
||||||
|
auto y = wl_fixed_to_double(surface_y);
|
||||||
|
|
||||||
|
const auto PDRIVER = (CWaylandOpenGLDriver*)data;
|
||||||
|
if (!PDRIVER->lastLSInFocus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PDRIVER->lastLSInFocus->mousePos = {x, y};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handlePointerButton(void* data, struct wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t button_state) {
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct wl_pointer_listener pointerListener = { .enter = handlePointerEnter, .leave = handlePointerLeave, .motion = handlePointerMotion, .button = handlePointerButton, .axis = handlePointerAxis };
|
||||||
|
|
||||||
|
static void handleCapabilities(void* data, wl_seat* wl_seat, uint32_t capabilities) {
|
||||||
|
if (capabilities & WL_SEAT_CAPABILITY_POINTER)
|
||||||
|
wl_pointer_add_listener(wl_seat_get_pointer(wl_seat), &pointerListener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct wl_seat_listener seatListener = { .capabilities = handleCapabilities };
|
||||||
|
|
||||||
|
static void geometry(void* data, wl_output* output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char* make, const char* model,
|
||||||
int32_t transform) {
|
int32_t transform) {
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
void mode(void* data, wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
|
static void mode(void* data, wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
|
||||||
const auto PMONITOR = (SWaylandOutput*)data;
|
const auto PMONITOR = (SWaylandOutput*)data;
|
||||||
PMONITOR->size = {width, height};
|
PMONITOR->size = {width, height};
|
||||||
PMONITOR->lsSize = {width, height};
|
PMONITOR->lsSize = {width, height};
|
||||||
@ -37,13 +79,13 @@ void mode(void* data, wl_output* output, uint32_t flags, int32_t width, int32_t
|
|||||||
PMONITOR->driver->wallpaperApplication->getOutput()->reset();
|
PMONITOR->driver->wallpaperApplication->getOutput()->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void done(void* data, wl_output* wl_output) {
|
static void done(void* data, wl_output* wl_output) {
|
||||||
const auto PMONITOR = (SWaylandOutput*)data;
|
const auto PMONITOR = (SWaylandOutput*)data;
|
||||||
|
|
||||||
PMONITOR->initialized = true;
|
PMONITOR->initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void scale(void* data, wl_output* wl_output, int32_t scale) {
|
static void scale(void* data, wl_output* wl_output, int32_t scale) {
|
||||||
const auto PMONITOR = (SWaylandOutput*)data;
|
const auto PMONITOR = (SWaylandOutput*)data;
|
||||||
|
|
||||||
PMONITOR->scale = scale;
|
PMONITOR->scale = scale;
|
||||||
@ -55,14 +97,14 @@ void scale(void* data, wl_output* wl_output, int32_t scale) {
|
|||||||
PMONITOR->driver->wallpaperApplication->getOutput()->reset();
|
PMONITOR->driver->wallpaperApplication->getOutput()->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void name(void* data, wl_output* wl_output, const char* name) {
|
static void name(void* data, wl_output* wl_output, const char* name) {
|
||||||
const auto PMONITOR = (SWaylandOutput*)data;
|
const auto PMONITOR = (SWaylandOutput*)data;
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
PMONITOR->name = name;
|
PMONITOR->name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void description(void* data, wl_output* wl_output, const char* description) {
|
static void description(void* data, wl_output* wl_output, const char* description) {
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +127,9 @@ static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name
|
|||||||
wl_output_add_listener(POUTPUT->output, &outputListener, POUTPUT);
|
wl_output_add_listener(POUTPUT->output, &outputListener, POUTPUT);
|
||||||
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
||||||
PDRIVER->waylandContext.layerShell = (zwlr_layer_shell_v1*)wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1);
|
PDRIVER->waylandContext.layerShell = (zwlr_layer_shell_v1*)wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1);
|
||||||
|
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||||
|
PDRIVER->waylandContext.seat = (wl_seat*)wl_registry_bind(registry, name, &wl_seat_interface, 1);
|
||||||
|
wl_seat_add_listener(PDRIVER->waylandContext.seat, &seatListener, PDRIVER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,6 +282,7 @@ CLayerSurface::CLayerSurface(CWaylandOpenGLDriver* pDriver, SWaylandOutput* pOut
|
|||||||
sLog.exception("Failed to get a layer surface");
|
sLog.exception("Failed to get a layer surface");
|
||||||
|
|
||||||
wl_region* region = wl_compositor_create_region(pDriver->waylandContext.compositor);
|
wl_region* region = wl_compositor_create_region(pDriver->waylandContext.compositor);
|
||||||
|
wl_region_add(region, 0, 0, INT32_MAX, INT32_MAX);
|
||||||
|
|
||||||
zwlr_layer_surface_v1_set_size(layerSurface, 0, 0);
|
zwlr_layer_surface_v1_set_size(layerSurface, 0, 0);
|
||||||
zwlr_layer_surface_v1_set_anchor(layerSurface, ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM);
|
zwlr_layer_surface_v1_set_anchor(layerSurface, ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM);
|
||||||
@ -254,6 +300,18 @@ CLayerSurface::CLayerSurface(CWaylandOpenGLDriver* pDriver, SWaylandOutput* pOut
|
|||||||
wl_display_roundtrip(pDriver->waylandContext.display);
|
wl_display_roundtrip(pDriver->waylandContext.display);
|
||||||
wl_display_flush(pDriver->waylandContext.display);
|
wl_display_flush(pDriver->waylandContext.display);
|
||||||
|
|
||||||
|
static const auto XCURSORSIZE = getenv("XCURSOR_SIZE") ? std::stoi(getenv("XCURSOR_SIZE")) : 24;
|
||||||
|
const auto PRCURSORTHEME = wl_cursor_theme_load(getenv("XCURSOR_THEME"), XCURSORSIZE * output->scale, pDriver->waylandContext.shm);
|
||||||
|
|
||||||
|
if (!PRCURSORTHEME)
|
||||||
|
sLog.exception("Failed to get a cursor theme");
|
||||||
|
|
||||||
|
pointer = wl_cursor_theme_get_cursor(PRCURSORTHEME, "left_ptr");
|
||||||
|
cursorSurface = wl_compositor_create_surface(pDriver->waylandContext.compositor);
|
||||||
|
|
||||||
|
if (!cursorSurface)
|
||||||
|
sLog.exception("Failed to get a cursor surface");
|
||||||
|
|
||||||
if (eglMakeCurrent(pDriver->eglContext.display, eglSurface, eglSurface, pDriver->eglContext.context) == EGL_FALSE)
|
if (eglMakeCurrent(pDriver->eglContext.display, eglSurface, eglSurface, pDriver->eglContext.context) == EGL_FALSE)
|
||||||
sLog.exception("Failed to make egl current");
|
sLog.exception("Failed to make egl current");
|
||||||
}
|
}
|
||||||
@ -291,18 +349,6 @@ CWaylandOpenGLDriver::CWaylandOpenGLDriver(const char* windowTitle, CApplication
|
|||||||
outputToUse = m_outputs[0].get();
|
outputToUse = m_outputs[0].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto XCURSORSIZE = getenv("XCURSOR_SIZE") ? std::stoi(getenv("XCURSOR_SIZE")) : 24;
|
|
||||||
const auto PRCURSORTHEME = wl_cursor_theme_load(NULL, XCURSORSIZE, waylandContext.shm);
|
|
||||||
|
|
||||||
if (!PRCURSORTHEME)
|
|
||||||
sLog.exception("Failed to get a cursor theme");
|
|
||||||
|
|
||||||
waylandContext.pointer = wl_cursor_theme_get_cursor(PRCURSORTHEME, "left_ptr");
|
|
||||||
waylandContext.cursorSurface = wl_compositor_create_surface(waylandContext.compositor);
|
|
||||||
|
|
||||||
if (!waylandContext.cursorSurface)
|
|
||||||
sLog.exception("Failed to get a cursor surface");
|
|
||||||
|
|
||||||
initEGL();
|
initEGL();
|
||||||
|
|
||||||
const auto PLS = (outputToUse->layerSurface = std::make_unique<CLayerSurface>(this, outputToUse)).get();
|
const auto PLS = (outputToUse->layerSurface = std::make_unique<CLayerSurface>(this, outputToUse)).get();
|
||||||
@ -409,3 +455,12 @@ void CWaylandOpenGLDriver::makeCurrent(const std::string& outputName) const {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CLayerSurface* CWaylandOpenGLDriver::surfaceToLS(wl_surface* surface) {
|
||||||
|
for (auto& o : m_outputs) {
|
||||||
|
if (o->layerSurface->surface == surface)
|
||||||
|
return o->layerSurface.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
@ -51,6 +51,9 @@ namespace WallpaperEngine::Render::Drivers
|
|||||||
glm::ivec2 size;
|
glm::ivec2 size;
|
||||||
wl_callback* frameCallback = nullptr;
|
wl_callback* frameCallback = nullptr;
|
||||||
SWaylandOutput* output = nullptr;
|
SWaylandOutput* output = nullptr;
|
||||||
|
glm::dvec2 mousePos = {0, 0};
|
||||||
|
wl_cursor* pointer = nullptr;
|
||||||
|
wl_surface* cursorSurface = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CWaylandOpenGLDriver : public CVideoDriver
|
class CWaylandOpenGLDriver : public CVideoDriver
|
||||||
@ -80,12 +83,12 @@ namespace WallpaperEngine::Render::Drivers
|
|||||||
wl_compositor* compositor = nullptr;
|
wl_compositor* compositor = nullptr;
|
||||||
wl_shm* shm = nullptr;
|
wl_shm* shm = nullptr;
|
||||||
zwlr_layer_shell_v1* layerShell = nullptr;
|
zwlr_layer_shell_v1* layerShell = nullptr;
|
||||||
wl_cursor* pointer = nullptr;
|
wl_seat* seat = nullptr;
|
||||||
wl_surface* cursorSurface = nullptr;
|
|
||||||
} waylandContext;
|
} waylandContext;
|
||||||
|
|
||||||
void onLayerClose(CLayerSurface*);
|
void onLayerClose(CLayerSurface*);
|
||||||
void resizeLSSurfaceEGL(CLayerSurface*);
|
void resizeLSSurfaceEGL(CLayerSurface*);
|
||||||
|
CLayerSurface* surfaceToLS(wl_surface*);
|
||||||
|
|
||||||
std::vector<std::unique_ptr<SWaylandOutput>> m_outputs;
|
std::vector<std::unique_ptr<SWaylandOutput>> m_outputs;
|
||||||
|
|
||||||
@ -98,6 +101,8 @@ namespace WallpaperEngine::Render::Drivers
|
|||||||
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = nullptr;
|
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = nullptr;
|
||||||
} eglContext;
|
} eglContext;
|
||||||
|
|
||||||
|
CLayerSurface* lastLSInFocus = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void initEGL();
|
void initEGL();
|
||||||
|
Loading…
Reference in New Issue
Block a user