wayland: various fixes and improvements

also added devices
This commit is contained in:
Vaxry 2024-06-21 15:49:28 +02:00
parent a7a8840400
commit d175f21619
6 changed files with 191 additions and 20 deletions

View file

@ -104,6 +104,7 @@ namespace Aquamarine {
} events; } events;
Hyprutils::Memory::CSharedPointer<IAllocator> allocator; Hyprutils::Memory::CSharedPointer<IAllocator> allocator;
bool ready = false;
private: private:
CBackend(); CBackend();

View file

@ -16,6 +16,8 @@ namespace Aquamarine {
class CWaylandBackend; class CWaylandBackend;
class CWaylandOutput; class CWaylandOutput;
typedef std::function<void(void)> FIdleCallback;
class CWaylandBuffer { class CWaylandBuffer {
public: public:
CWaylandBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_); CWaylandBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_);
@ -55,6 +57,12 @@ namespace Aquamarine {
Hyprutils::Memory::CSharedPointer<CWaylandBuffer> wlBufferFromBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer); Hyprutils::Memory::CSharedPointer<CWaylandBuffer> wlBufferFromBuffer(Hyprutils::Memory::CSharedPointer<IBuffer> buffer);
void sendFrameAndSetCallback(); void sendFrameAndSetCallback();
void onFrameDone();
// frame loop
bool frameScheduledWhileWaiting = false;
bool readyForFrameCallback = false; // true after attaching a buffer
bool frameScheduled = false;
struct { struct {
std::vector<std::pair<Hyprutils::Memory::CWeakPointer<IBuffer>, Hyprutils::Memory::CSharedPointer<CWaylandBuffer>>> buffers; std::vector<std::pair<Hyprutils::Memory::CWeakPointer<IBuffer>, Hyprutils::Memory::CSharedPointer<CWaylandBuffer>>> buffers;
@ -123,9 +131,10 @@ namespace Aquamarine {
// //
Hyprutils::Memory::CWeakPointer<CBackend> backend; Hyprutils::Memory::CWeakPointer<CBackend> backend;
std::vector<Hyprutils::Memory::CSharedPointer<CWaylandOutput>> outputs, scheduledFrames; std::vector<Hyprutils::Memory::CSharedPointer<CWaylandOutput>> outputs;
std::vector<Hyprutils::Memory::CSharedPointer<CWaylandKeyboard>> keyboards; std::vector<Hyprutils::Memory::CSharedPointer<CWaylandKeyboard>> keyboards;
std::vector<Hyprutils::Memory::CSharedPointer<CWaylandPointer>> pointers; std::vector<Hyprutils::Memory::CSharedPointer<CWaylandPointer>> pointers;
std::vector<FIdleCallback> idleCallbacks;
// pointer focus // pointer focus
Hyprutils::Memory::CWeakPointer<CWaylandOutput> focusedOutput; Hyprutils::Memory::CWeakPointer<CWaylandOutput> focusedOutput;

View file

@ -45,11 +45,25 @@ namespace Aquamarine {
AQ_POINTER_AXIS_HORIZONTAL, AQ_POINTER_AXIS_HORIZONTAL,
}; };
enum ePointerAxisSource {
AQ_POINTER_AXIS_SOURCE_WHEEL = 0,
AQ_POINTER_AXIS_SOURCE_FINGER,
AQ_POINTER_AXIS_SOURCE_CONTINUOUS,
AQ_POINTER_AXIS_SOURCE_TILT,
};
enum ePointerAxisRelativeDirection {
AQ_POINTER_AXIS_RELATIVE_IDENTICAL = 0,
AQ_POINTER_AXIS_RELATIVE_INVERTED,
};
struct SMoveEvent { struct SMoveEvent {
Hyprutils::Math::Vector2D delta; uint32_t timeMs = 0;
Hyprutils::Math::Vector2D delta, unaccel;
}; };
struct SWarpEvent { struct SWarpEvent {
uint32_t timeMs = 0;
Hyprutils::Math::Vector2D absolute; Hyprutils::Math::Vector2D absolute;
}; };
@ -62,7 +76,52 @@ namespace Aquamarine {
struct SAxisEvent { struct SAxisEvent {
uint32_t timeMs = 0; uint32_t timeMs = 0;
ePointerAxis axis = AQ_POINTER_AXIS_VERTICAL; ePointerAxis axis = AQ_POINTER_AXIS_VERTICAL;
double value = 0.0; ePointerAxisSource source = AQ_POINTER_AXIS_SOURCE_WHEEL;
ePointerAxisRelativeDirection direction = AQ_POINTER_AXIS_RELATIVE_IDENTICAL;
double delta = 0.0, discrete = 0.0;
};
struct SSwipeBeginEvent {
uint32_t timeMs = 0;
uint32_t fingers = 0;
};
struct SSwipeUpdateEvent {
uint32_t timeMs = 0;
uint32_t fingers = 0;
Hyprutils::Math::Vector2D delta;
};
struct SSwipeEndEvent {
uint32_t timeMs = 0;
bool cancelled = false;
};
struct SPinchBeginEvent {
uint32_t timeMs = 0;
uint32_t fingers = 0;
};
struct SPinchUpdateEvent {
uint32_t timeMs = 0;
uint32_t fingers = 0;
Hyprutils::Math::Vector2D delta;
double scale = 1.0, rotation = 0.0;
};
struct SPinchEndEvent {
uint32_t timeMs = 0;
bool cancelled = false;
};
struct SHoldBeginEvent {
uint32_t timeMs = 0;
uint32_t fingers = 0;
};
struct SHoldEndEvent {
uint32_t timeMs = 0;
bool cancelled = false;
}; };
struct { struct {
@ -72,6 +131,85 @@ namespace Aquamarine {
Hyprutils::Signal::CSignal button; Hyprutils::Signal::CSignal button;
Hyprutils::Signal::CSignal axis; Hyprutils::Signal::CSignal axis;
Hyprutils::Signal::CSignal frame; Hyprutils::Signal::CSignal frame;
Hyprutils::Signal::CSignal swipeBegin;
Hyprutils::Signal::CSignal swipeUpdate;
Hyprutils::Signal::CSignal swipeEnd;
Hyprutils::Signal::CSignal pinchBegin;
Hyprutils::Signal::CSignal pinchUpdate;
Hyprutils::Signal::CSignal pinchEnd;
Hyprutils::Signal::CSignal holdBegin;
Hyprutils::Signal::CSignal holdEnd;
} events;
};
class ITouch {
public:
virtual ~ITouch() {
events.destroy.emit();
}
virtual libinput_device* getLibinputHandle();
virtual const std::string& getName() = 0;
struct SDownEvent {
uint32_t timeMs = 0;
int32_t touchID = 0;
Hyprutils::Math::Vector2D pos;
};
struct SUpEvent {
uint32_t timeMs = 0;
int32_t touchID = 0;
};
struct SMotionEvent {
uint32_t timeMs = 0;
int32_t touchID = 0;
Hyprutils::Math::Vector2D pos;
};
struct SCancelEvent {
uint32_t timeMs = 0;
int32_t touchID = 0;
};
struct {
Hyprutils::Signal::CSignal destroy;
Hyprutils::Signal::CSignal move;
Hyprutils::Signal::CSignal down;
Hyprutils::Signal::CSignal up;
Hyprutils::Signal::CSignal cancel;
Hyprutils::Signal::CSignal frame;
} events;
};
class ITablet {
public:
// FIXME:
struct {
Hyprutils::Signal::CSignal destroy;
} events;
};
class ITabletTool {
public:
// FIXME:
struct {
Hyprutils::Signal::CSignal destroy;
} events;
};
class ITabletPad {
public:
// FIXME:
struct {
Hyprutils::Signal::CSignal destroy;
} events; } events;
}; };
} }

View file

@ -48,7 +48,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
auto modName = drmGetFormatModifierName(attrs.modifier); auto modName = drmGetFormatModifierName(attrs.modifier);
allocator->backend->log( allocator->backend->log(
AQ_LOG_ERROR, AQ_LOG_DEBUG,
std::format("GBM: Allocated a new buffer with size {} and format {} with modifier {}", attrs.size, fourccToName(attrs.format), modName ? modName : "Unknown")); std::format("GBM: Allocated a new buffer with size {} and format {} with modifier {}", attrs.size, fourccToName(attrs.format), modName ? modName : "Unknown"));
free(modName); free(modName);

View file

@ -103,6 +103,7 @@ bool Aquamarine::CBackend::start() {
if (!allocator) if (!allocator)
return false; return false;
ready = true;
for (auto& b : implementations) { for (auto& b : implementations) {
b->onReady(); b->onReady();
} }

View file

@ -88,7 +88,7 @@ int Aquamarine::CWaylandBackend::drmFD() {
void Aquamarine::CWaylandBackend::createOutput(const std::string& szName) { void Aquamarine::CWaylandBackend::createOutput(const std::string& szName) {
auto o = outputs.emplace_back(SP<CWaylandOutput>(new CWaylandOutput(szName, self))); auto o = outputs.emplace_back(SP<CWaylandOutput>(new CWaylandOutput(szName, self)));
o->self = o; o->self = o;
backend->events.newOutput.emit(SP<IOutput>(o)); idleCallbacks.emplace_back([this, o]() { backend->events.newOutput.emit(SP<IOutput>(o)); });
} }
int Aquamarine::CWaylandBackend::pollFD() { int Aquamarine::CWaylandBackend::pollFD() {
@ -114,11 +114,12 @@ bool Aquamarine::CWaylandBackend::dispatchEvents() {
} while (ret > 0); } while (ret > 0);
// dispatch frames // dispatch frames
for (auto& f : scheduledFrames) { if (backend->ready) {
f->events.frame.emit(); for (auto& f : idleCallbacks) {
f();
}
idleCallbacks.clear();
} }
scheduledFrames.clear();
return true; return true;
} }
@ -189,7 +190,11 @@ Aquamarine::CWaylandPointer::CWaylandPointer(SP<CCWlPointer> pointer_, Hyprutils
Vector2D local = {wl_fixed_to_double(x), wl_fixed_to_double(y)}; Vector2D local = {wl_fixed_to_double(x), wl_fixed_to_double(y)};
local = local / size; local = local / size;
timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
events.warp.emit(SWarpEvent{ events.warp.emit(SWarpEvent{
.timeMs = (uint32_t)(now.tv_sec * 1000 + now.tv_nsec / 1000000),
.absolute = local, .absolute = local,
}); });
}); });
@ -219,7 +224,7 @@ Aquamarine::CWaylandPointer::CWaylandPointer(SP<CCWlPointer> pointer_, Hyprutils
events.axis.emit(SAxisEvent{ events.axis.emit(SAxisEvent{
.timeMs = timeMs, .timeMs = timeMs,
.axis = axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL ? AQ_POINTER_AXIS_HORIZONTAL : AQ_POINTER_AXIS_VERTICAL, .axis = axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL ? AQ_POINTER_AXIS_HORIZONTAL : AQ_POINTER_AXIS_VERTICAL,
.value = wl_fixed_to_double(value), .delta = wl_fixed_to_double(value),
}); });
}); });
@ -241,13 +246,13 @@ void Aquamarine::CWaylandBackend::initSeat() {
if (HAS_KEYBOARD && keyboards.empty()) { if (HAS_KEYBOARD && keyboards.empty()) {
auto k = keyboards.emplace_back(makeShared<CWaylandKeyboard>(makeShared<CCWlKeyboard>(waylandState.seat->sendGetKeyboard()), self)); auto k = keyboards.emplace_back(makeShared<CWaylandKeyboard>(makeShared<CCWlKeyboard>(waylandState.seat->sendGetKeyboard()), self));
backend->events.newKeyboard.emit(SP<IKeyboard>(k)); idleCallbacks.emplace_back([this, k]() { backend->events.newKeyboard.emit(SP<IKeyboard>(k)); });
} else if (!HAS_KEYBOARD && !keyboards.empty()) } else if (!HAS_KEYBOARD && !keyboards.empty())
keyboards.clear(); keyboards.clear();
if (HAS_POINTER && pointers.empty()) { if (HAS_POINTER && pointers.empty()) {
auto p = pointers.emplace_back(makeShared<CWaylandPointer>(makeShared<CCWlPointer>(waylandState.seat->sendGetPointer()), self)); auto p = pointers.emplace_back(makeShared<CWaylandPointer>(makeShared<CCWlPointer>(waylandState.seat->sendGetPointer()), self));
backend->events.newPointer.emit(SP<IPointer>(p)); idleCallbacks.emplace_back([this, p]() { backend->events.newPointer.emit(SP<IPointer>(p)); });
} else if (!HAS_POINTER && !pointers.empty()) } else if (!HAS_POINTER && !pointers.empty())
pointers.clear(); pointers.clear();
}); });
@ -436,6 +441,8 @@ bool Aquamarine::CWaylandOutput::commit() {
waylandState.surface->sendDamageBuffer(0, 0, INT32_MAX, INT32_MAX); waylandState.surface->sendDamageBuffer(0, 0, INT32_MAX, INT32_MAX);
waylandState.surface->sendCommit(); waylandState.surface->sendCommit();
readyForFrameCallback = true;
return true; return true;
} }
@ -466,14 +473,24 @@ SP<CWaylandBuffer> Aquamarine::CWaylandOutput::wlBufferFromBuffer(SP<IBuffer> bu
void Aquamarine::CWaylandOutput::sendFrameAndSetCallback() { void Aquamarine::CWaylandOutput::sendFrameAndSetCallback() {
events.frame.emit(); events.frame.emit();
if (waylandState.frameCallback) frameScheduled = false;
if (waylandState.frameCallback || !readyForFrameCallback)
return; return;
waylandState.frameCallback = makeShared<CCWlCallback>(waylandState.surface->sendFrame()); waylandState.frameCallback = makeShared<CCWlCallback>(waylandState.surface->sendFrame());
waylandState.frameCallback->setDone([this](CCWlCallback* r, uint32_t ms) { waylandState.frameCallback->setDone([this](CCWlCallback* r, uint32_t ms) { onFrameDone(); });
events.frame.emit(); }
void Aquamarine::CWaylandOutput::onFrameDone() {
waylandState.frameCallback.reset(); waylandState.frameCallback.reset();
}); readyForFrameCallback = false;
if (frameScheduledWhileWaiting)
sendFrameAndSetCallback();
else
events.frame.emit();
frameScheduledWhileWaiting = false;
} }
bool Aquamarine::CWaylandOutput::setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot) { bool Aquamarine::CWaylandOutput::setCursor(Hyprutils::Memory::CSharedPointer<IBuffer> buffer, const Hyprutils::Math::Vector2D& hotspot) {
@ -485,10 +502,15 @@ void Aquamarine::CWaylandOutput::moveCursor(const Hyprutils::Math::Vector2D& coo
} }
void Aquamarine::CWaylandOutput::scheduleFrame() { void Aquamarine::CWaylandOutput::scheduleFrame() {
if (std::find(backend->scheduledFrames.begin(), backend->scheduledFrames.end(), self.lock()) != backend->scheduledFrames.end()) if (frameScheduled)
return; return;
backend->scheduledFrames.emplace_back(self.lock()); frameScheduled = true;
if (waylandState.frameCallback)
frameScheduledWhileWaiting = true;
else
backend->idleCallbacks.emplace_back([this]() { sendFrameAndSetCallback(); });
} }
Aquamarine::CWaylandBuffer::CWaylandBuffer(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_) : buffer(buffer_), backend(backend_) { Aquamarine::CWaylandBuffer::CWaylandBuffer(SP<IBuffer> buffer_, Hyprutils::Memory::CWeakPointer<CWaylandBackend> backend_) : buffer(buffer_), backend(backend_) {