Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 55 additions & 40 deletions src/window/wayland/wayland_display_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ WaylandDisplayBackend::WaylandDisplayBackend()
if (interface == wayland::data_device_manager_t::interface_name)
s_waylandRegistry.bind(name, m_DataDeviceManager, 3);
if (interface == wayland::xdg_wm_base_t::interface_name)
s_waylandRegistry.bind(name, m_XDGWMBase, version);
/* Setting the version to anything higher than 4 will cause an
* "interface 'xdg_toplevel' has no event 3" error.
* Presumably referring to wm_capabilities event.
*/
s_waylandRegistry.bind(name, m_XDGWMBase, 4);
if (interface == wayland::zxdg_output_manager_v1_t::interface_name)
s_waylandRegistry.bind(name, m_XDGOutputManager, version);
if (interface == wayland::zxdg_exporter_v2_t::interface_name)
Expand Down Expand Up @@ -66,6 +70,17 @@ WaylandDisplayBackend::WaylandDisplayBackend()
if (!m_RelativePointerManager)
throw std::runtime_error("WaylandDisplayBackend: relative-pointer-unstable-v1 is required!");

m_keyboardDelayTimer = ZTimer();
m_keyboardRepeatTimer = ZTimer();

m_keyboardDelayTimer.SetCallback([this] () { OnKeyboardDelayEnd(); });
m_keyboardRepeatTimer.SetCallback([this] () { OnKeyboardRepeat(); });

m_keyboardRepeatTimer.SetRepeating(true);

m_previousTime = ZTimer::Clock::now();
m_currentTime = ZTimer::Clock::now();

m_waylandOutput.on_mode() = [this] (wayland::output_mode flags, int32_t width, int32_t height, int32_t refresh) {
s_ScreenSize = Size(width, height);
};
Expand All @@ -75,8 +90,7 @@ WaylandDisplayBackend::WaylandDisplayBackend()
};

m_waylandSeat.on_capabilities() = [this] (uint32_t capabilities) {
hasKeyboard = capabilities & wayland::seat_capability::keyboard;
hasPointer = capabilities & wayland::seat_capability::pointer;
OnCapabilitiesEvent(capabilities);
};

m_XDGOutput = m_XDGOutputManager.get_xdg_output(m_waylandOutput);
Expand Down Expand Up @@ -158,24 +172,6 @@ WaylandDisplayBackend::WaylandDisplayBackend()

s_waylandDisplay.roundtrip();

// To do: this shouldn't really be fatal. The user might have forgotten to plug in their keyboard or mouse.
if (!hasKeyboard)
throw std::runtime_error("No keyboard detected!");
if (!hasPointer)
throw std::runtime_error("No pointer device detected!");

m_waylandKeyboard = m_waylandSeat.get_keyboard();
m_waylandPointer = m_waylandSeat.get_pointer();
m_RelativePointer = m_RelativePointerManager.get_relative_pointer(m_waylandPointer);

if (m_CursorShapeManager && m_waylandPointer)
{
// Opt to Cursor Shape Protocol instead
m_CursorShapeDevice = m_CursorShapeManager.get_pointer(m_waylandPointer);
}

ConnectDeviceEvents();

m_cursorSurface = m_waylandCompositor.create_surface();
SetCursor(StandardCursor::arrow, nullptr);
}
Expand All @@ -189,7 +185,7 @@ WaylandDisplayBackend::~WaylandDisplayBackend()
xkb_state_unref(m_KeyboardState);
}

void WaylandDisplayBackend::ConnectDeviceEvents()
void WaylandDisplayBackend::ConnectKeyboardEvents()
{
m_KeymapContext = xkb_context_new(XKB_CONTEXT_NO_FLAGS);

Expand Down Expand Up @@ -260,14 +256,23 @@ void WaylandDisplayBackend::ConnectDeviceEvents()
OnKeyboardCharEvent(buf, state);
};

m_waylandKeyboard.on_repeat_info() = [this] (int32_t rate, int32_t delay) {
// rate is characters per second, delay is in milliseconds
m_keyboardDelayTimer.SetDuration(ZTimer::Duration(delay));
m_keyboardRepeatTimer.SetDuration(ZTimer::Duration(1000.0 / rate));
};
}

void WaylandDisplayBackend::ConnectMouseEvents()
{
m_waylandPointer.on_enter() = [this](uint32_t serial, wayland::surface_t surfaceEntered, double surfaceX, double surfaceY) {
// Keep track of the mouse serial for using it in Cursor Shape protocol
m_MouseSerial = serial;

// Find the window to focus on by checking the surface window owns.
if (!m_MouseFocusWindow || m_MouseFocusWindow->GetWindowSurface() != surfaceEntered)
{
for (auto win: s_Windows)
for (const auto win: s_Windows)
{
if (win->GetWindowSurface() == surfaceEntered)
{
Expand Down Expand Up @@ -396,23 +401,6 @@ void WaylandDisplayBackend::ConnectDeviceEvents()
// Reset everything once all the events are processed
currentPointerEvent = {0};
};

m_keyboardDelayTimer = ZTimer();
m_keyboardRepeatTimer = ZTimer();

m_waylandKeyboard.on_repeat_info() = [this] (int32_t rate, int32_t delay) {
// rate is characters per second, delay is in milliseconds
m_keyboardDelayTimer.SetDuration(ZTimer::Duration(delay));
m_keyboardRepeatTimer.SetDuration(ZTimer::Duration(1000.0 / rate));
};

m_keyboardDelayTimer.SetCallback([this] () { OnKeyboardDelayEnd(); });
m_keyboardRepeatTimer.SetCallback([this] () { OnKeyboardRepeat(); });

m_keyboardRepeatTimer.SetRepeating(true);

m_previousTime = ZTimer::Clock::now();
m_currentTime = ZTimer::Clock::now();
}

void WaylandDisplayBackend::OnKeyboardKeyEvent(xkb_keysym_t xkbKeySym, wayland::keyboard_key_state state)
Expand Down Expand Up @@ -518,6 +506,33 @@ void WaylandDisplayBackend::OnMouseWheelEvent(InputKey button)
m_MouseFocusWindow->windowHost->OnWindowMouseWheel(m_MouseFocusWindow->m_SurfaceMousePos, button);
}

void WaylandDisplayBackend::OnCapabilitiesEvent(uint32_t capabilities)
{
hasKeyboard = capabilities & wayland::seat_capability::keyboard;
hasPointer = capabilities & wayland::seat_capability::pointer;

if (hasKeyboard)
{
m_waylandKeyboard = m_waylandSeat.get_keyboard();
ConnectKeyboardEvents();
}

if (hasPointer)
{
m_waylandPointer = m_waylandSeat.get_pointer();

m_RelativePointer = m_RelativePointerManager.get_relative_pointer(m_waylandPointer);

if (m_CursorShapeManager)
{
// Opt to Cursor Shape Protocol instead
m_CursorShapeDevice = m_CursorShapeManager.get_pointer(m_waylandPointer);
}

ConnectMouseEvents();
}
}

void WaylandDisplayBackend::SetCursor(StandardCursor cursor, std::shared_ptr<CustomCursor> custom)
{
if (m_CursorShapeDevice)
Expand Down
4 changes: 3 additions & 1 deletion src/window/wayland/wayland_display_backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ class WaylandDisplayBackend : public DisplayBackend
void UpdateTimers();
void WaitForEvents(int timeout);
int GetTimerTimeout();
void ConnectDeviceEvents();
void ConnectKeyboardEvents();
void ConnectMouseEvents();
void OnKeyboardKeyEvent(xkb_keysym_t xkbKeySym, wayland::keyboard_key_state state);
void OnKeyboardCharEvent(const char* ch, wayland::keyboard_key_state state);
void OnKeyboardDelayEnd();
Expand All @@ -171,6 +172,7 @@ class WaylandDisplayBackend : public DisplayBackend
void OnMouseMoveEvent(Point surfacePos);
void OnMouseMoveRawEvent(int surfaceX, int surfaceY);
void OnMouseWheelEvent(InputKey button);
void OnCapabilitiesEvent(uint32_t capabilities);

InputKey XKBKeySymToInputKey(xkb_keysym_t keySym);
InputKey LinuxInputEventCodeToInputKey(uint32_t inputCode);
Expand Down