mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 03:46:00 +01:00
wayland: various fixes and improvements
also added devices
This commit is contained in:
parent
a7a8840400
commit
d175f21619
6 changed files with 191 additions and 20 deletions
|
@ -104,6 +104,7 @@ namespace Aquamarine {
|
|||
} events;
|
||||
|
||||
Hyprutils::Memory::CSharedPointer<IAllocator> allocator;
|
||||
bool ready = false;
|
||||
|
||||
private:
|
||||
CBackend();
|
||||
|
|
|
@ -16,6 +16,8 @@ namespace Aquamarine {
|
|||
class CWaylandBackend;
|
||||
class CWaylandOutput;
|
||||
|
||||
typedef std::function<void(void)> FIdleCallback;
|
||||
|
||||
class CWaylandBuffer {
|
||||
public:
|
||||
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);
|
||||
|
||||
void sendFrameAndSetCallback();
|
||||
void onFrameDone();
|
||||
|
||||
// frame loop
|
||||
bool frameScheduledWhileWaiting = false;
|
||||
bool readyForFrameCallback = false; // true after attaching a buffer
|
||||
bool frameScheduled = false;
|
||||
|
||||
struct {
|
||||
std::vector<std::pair<Hyprutils::Memory::CWeakPointer<IBuffer>, Hyprutils::Memory::CSharedPointer<CWaylandBuffer>>> buffers;
|
||||
|
@ -123,9 +131,10 @@ namespace Aquamarine {
|
|||
|
||||
//
|
||||
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<CWaylandPointer>> pointers;
|
||||
std::vector<FIdleCallback> idleCallbacks;
|
||||
|
||||
// pointer focus
|
||||
Hyprutils::Memory::CWeakPointer<CWaylandOutput> focusedOutput;
|
||||
|
|
|
@ -45,11 +45,25 @@ namespace Aquamarine {
|
|||
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 {
|
||||
Hyprutils::Math::Vector2D delta;
|
||||
uint32_t timeMs = 0;
|
||||
Hyprutils::Math::Vector2D delta, unaccel;
|
||||
};
|
||||
|
||||
struct SWarpEvent {
|
||||
uint32_t timeMs = 0;
|
||||
Hyprutils::Math::Vector2D absolute;
|
||||
};
|
||||
|
||||
|
@ -62,7 +76,52 @@ namespace Aquamarine {
|
|||
struct SAxisEvent {
|
||||
uint32_t timeMs = 0;
|
||||
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 {
|
||||
|
@ -72,6 +131,85 @@ namespace Aquamarine {
|
|||
Hyprutils::Signal::CSignal button;
|
||||
Hyprutils::Signal::CSignal axis;
|
||||
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;
|
||||
};
|
||||
}
|
|
@ -48,7 +48,7 @@ Aquamarine::CGBMBuffer::CGBMBuffer(const SAllocatorBufferParams& params, Hypruti
|
|||
auto modName = drmGetFormatModifierName(attrs.modifier);
|
||||
|
||||
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"));
|
||||
|
||||
free(modName);
|
||||
|
|
|
@ -103,6 +103,7 @@ bool Aquamarine::CBackend::start() {
|
|||
if (!allocator)
|
||||
return false;
|
||||
|
||||
ready = true;
|
||||
for (auto& b : implementations) {
|
||||
b->onReady();
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@ int Aquamarine::CWaylandBackend::drmFD() {
|
|||
void Aquamarine::CWaylandBackend::createOutput(const std::string& szName) {
|
||||
auto o = outputs.emplace_back(SP<CWaylandOutput>(new CWaylandOutput(szName, self)));
|
||||
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() {
|
||||
|
@ -114,11 +114,12 @@ bool Aquamarine::CWaylandBackend::dispatchEvents() {
|
|||
} while (ret > 0);
|
||||
|
||||
// dispatch frames
|
||||
for (auto& f : scheduledFrames) {
|
||||
f->events.frame.emit();
|
||||
if (backend->ready) {
|
||||
for (auto& f : idleCallbacks) {
|
||||
f();
|
||||
}
|
||||
idleCallbacks.clear();
|
||||
}
|
||||
|
||||
scheduledFrames.clear();
|
||||
|
||||
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)};
|
||||
local = local / size;
|
||||
|
||||
timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
events.warp.emit(SWarpEvent{
|
||||
.timeMs = (uint32_t)(now.tv_sec * 1000 + now.tv_nsec / 1000000),
|
||||
.absolute = local,
|
||||
});
|
||||
});
|
||||
|
@ -219,7 +224,7 @@ Aquamarine::CWaylandPointer::CWaylandPointer(SP<CCWlPointer> pointer_, Hyprutils
|
|||
events.axis.emit(SAxisEvent{
|
||||
.timeMs = timeMs,
|
||||
.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()) {
|
||||
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())
|
||||
keyboards.clear();
|
||||
|
||||
if (HAS_POINTER && pointers.empty()) {
|
||||
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())
|
||||
pointers.clear();
|
||||
});
|
||||
|
@ -436,6 +441,8 @@ bool Aquamarine::CWaylandOutput::commit() {
|
|||
waylandState.surface->sendDamageBuffer(0, 0, INT32_MAX, INT32_MAX);
|
||||
waylandState.surface->sendCommit();
|
||||
|
||||
readyForFrameCallback = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -466,14 +473,24 @@ SP<CWaylandBuffer> Aquamarine::CWaylandOutput::wlBufferFromBuffer(SP<IBuffer> bu
|
|||
|
||||
void Aquamarine::CWaylandOutput::sendFrameAndSetCallback() {
|
||||
events.frame.emit();
|
||||
if (waylandState.frameCallback)
|
||||
frameScheduled = false;
|
||||
if (waylandState.frameCallback || !readyForFrameCallback)
|
||||
return;
|
||||
|
||||
waylandState.frameCallback = makeShared<CCWlCallback>(waylandState.surface->sendFrame());
|
||||
waylandState.frameCallback->setDone([this](CCWlCallback* r, uint32_t ms) {
|
||||
events.frame.emit();
|
||||
waylandState.frameCallback->setDone([this](CCWlCallback* r, uint32_t ms) { onFrameDone(); });
|
||||
}
|
||||
|
||||
void Aquamarine::CWaylandOutput::onFrameDone() {
|
||||
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) {
|
||||
|
@ -485,10 +502,15 @@ void Aquamarine::CWaylandOutput::moveCursor(const Hyprutils::Math::Vector2D& coo
|
|||
}
|
||||
|
||||
void Aquamarine::CWaylandOutput::scheduleFrame() {
|
||||
if (std::find(backend->scheduledFrames.begin(), backend->scheduledFrames.end(), self.lock()) != backend->scheduledFrames.end())
|
||||
if (frameScheduled)
|
||||
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_) {
|
||||
|
|
Loading…
Reference in a new issue