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
|
||||
CInputContext::CInputContext (CWaylandOpenGLDriver& videoDriver) :
|
||||
m_mouse (nullptr)
|
||||
m_mouse (&videoDriver)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -5,10 +5,20 @@ using namespace WallpaperEngine::Input;
|
||||
|
||||
CMouseInput::CMouseInput (GLFWwindow* window) : position (), m_mousePosition (), m_window (window) {}
|
||||
|
||||
CMouseInput::CMouseInput(WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver* driver) {
|
||||
waylandDriver = driver;
|
||||
}
|
||||
|
||||
void CMouseInput::update ()
|
||||
{
|
||||
if (!m_window)
|
||||
if (!m_window) {
|
||||
if (!waylandDriver || !waylandDriver->lastLSInFocus)
|
||||
return;
|
||||
|
||||
this->position = waylandDriver->lastLSInFocus->mousePos;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// update current mouse position
|
||||
glfwGetCursorPos (this->m_window, &this->m_mousePosition.x, &this->m_mousePosition.y);
|
||||
|
@ -1,8 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Render/Drivers/CWaylandOpenGLDriver.h"
|
||||
|
||||
#include <glm/vec2.hpp>
|
||||
#include "GLFW/glfw3.h"
|
||||
|
||||
|
||||
namespace WallpaperEngine::Input
|
||||
{
|
||||
/**
|
||||
@ -13,6 +16,9 @@ namespace WallpaperEngine::Input
|
||||
public:
|
||||
explicit CMouseInput(GLFWwindow* window);
|
||||
|
||||
explicit CMouseInput(WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver* driver);
|
||||
|
||||
|
||||
/**
|
||||
* Takes current mouse position and updates it
|
||||
*/
|
||||
@ -27,12 +33,17 @@ namespace WallpaperEngine::Input
|
||||
/**
|
||||
* The GLFW window to get mouse position from
|
||||
*/
|
||||
GLFWwindow* m_window;
|
||||
GLFWwindow* m_window = nullptr;
|
||||
|
||||
/**
|
||||
* The current mouse position
|
||||
*/
|
||||
glm::dvec2 m_mousePosition;
|
||||
|
||||
/**
|
||||
* Wayland: Driver
|
||||
*/
|
||||
WallpaperEngine::Render::Drivers::CWaylandOpenGLDriver* waylandDriver = nullptr;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,54 @@ extern "C" {
|
||||
|
||||
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) {
|
||||
// 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;
|
||||
PMONITOR->size = {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();
|
||||
}
|
||||
|
||||
void done(void* data, wl_output* wl_output) {
|
||||
static void done(void* data, wl_output* wl_output) {
|
||||
const auto PMONITOR = (SWaylandOutput*)data;
|
||||
|
||||
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;
|
||||
|
||||
PMONITOR->scale = scale;
|
||||
@ -55,14 +97,14 @@ void scale(void* data, wl_output* wl_output, int32_t scale) {
|
||||
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;
|
||||
|
||||
if (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
|
||||
}
|
||||
|
||||
@ -85,6 +127,9 @@ static void handleGlobal(void *data, struct wl_registry *registry, uint32_t name
|
||||
wl_output_add_listener(POUTPUT->output, &outputListener, POUTPUT);
|
||||
} 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);
|
||||
} 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");
|
||||
|
||||
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_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_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)
|
||||
sLog.exception("Failed to make egl current");
|
||||
}
|
||||
@ -291,18 +349,6 @@ CWaylandOpenGLDriver::CWaylandOpenGLDriver(const char* windowTitle, CApplication
|
||||
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();
|
||||
|
||||
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;
|
||||
wl_callback* frameCallback = nullptr;
|
||||
SWaylandOutput* output = nullptr;
|
||||
glm::dvec2 mousePos = {0, 0};
|
||||
wl_cursor* pointer = nullptr;
|
||||
wl_surface* cursorSurface = nullptr;
|
||||
};
|
||||
|
||||
class CWaylandOpenGLDriver : public CVideoDriver
|
||||
@ -80,12 +83,12 @@ namespace WallpaperEngine::Render::Drivers
|
||||
wl_compositor* compositor = nullptr;
|
||||
wl_shm* shm = nullptr;
|
||||
zwlr_layer_shell_v1* layerShell = nullptr;
|
||||
wl_cursor* pointer = nullptr;
|
||||
wl_surface* cursorSurface = nullptr;
|
||||
wl_seat* seat = nullptr;
|
||||
} waylandContext;
|
||||
|
||||
void onLayerClose(CLayerSurface*);
|
||||
void resizeLSSurfaceEGL(CLayerSurface*);
|
||||
CLayerSurface* surfaceToLS(wl_surface*);
|
||||
|
||||
std::vector<std::unique_ptr<SWaylandOutput>> m_outputs;
|
||||
|
||||
@ -98,6 +101,8 @@ namespace WallpaperEngine::Render::Drivers
|
||||
PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC eglCreatePlatformWindowSurfaceEXT = nullptr;
|
||||
} eglContext;
|
||||
|
||||
CLayerSurface* lastLSInFocus = nullptr;
|
||||
|
||||
private:
|
||||
|
||||
void initEGL();
|
||||
|
Loading…
Reference in New Issue
Block a user