mirror of
https://github.com/hyprwm/aquamarine.git
synced 2024-11-17 02:35:59 +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;
|
} events;
|
||||||
|
|
||||||
Hyprutils::Memory::CSharedPointer<IAllocator> allocator;
|
Hyprutils::Memory::CSharedPointer<IAllocator> allocator;
|
||||||
|
bool ready = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CBackend();
|
CBackend();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -60,9 +74,54 @@ 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;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,12 +114,13 @@ 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(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aquamarine::CWaylandOutput::onFrameDone() {
|
||||||
|
waylandState.frameCallback.reset();
|
||||||
|
readyForFrameCallback = false;
|
||||||
|
|
||||||
|
if (frameScheduledWhileWaiting)
|
||||||
|
sendFrameAndSetCallback();
|
||||||
|
else
|
||||||
events.frame.emit();
|
events.frame.emit();
|
||||||
waylandState.frameCallback.reset();
|
|
||||||
});
|
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_) {
|
||||||
|
|
Loading…
Reference in a new issue