libinput: handle tablet axis on proximity, tip and button events (#194)

There can be axis changes on other tablet events, so we need to handle
axis changes on proximity, tip and button events too.
This commit is contained in:
Maxime Nordier 2025-07-19 16:46:21 +02:00 committed by GitHub
parent e31b575d19
commit 141a991678
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 68 additions and 63 deletions

View file

@ -237,6 +237,7 @@ namespace Aquamarine {
void dispatchLibinputEvents();
void dispatchLibseatEvents();
void handleLibinputEvent(libinput_event* e);
void handleLibinputTabletToolAxis(libinput_event* e);
friend class CSessionDevice;
friend class CLibinputDevice;

View file

@ -409,7 +409,6 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
}
auto hlDevice = ((CLibinputDevice*)data)->self.lock();
bool destroyTool = false;
switch (eventType) {
case LIBINPUT_EVENT_DEVICE_ADDED:
@ -648,7 +647,7 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
break;
}
// --------- tbalet
// --------- tablet
case LIBINPUT_EVENT_TABLET_PAD_BUTTON: {
auto tpe = libinput_event_get_tablet_pad_event(e);
@ -700,18 +699,56 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
.in = libinput_event_tablet_tool_get_proximity_state(tte) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN,
});
destroyTool = !libinput_tablet_tool_is_unique(libinput_event_tablet_tool_get_tool(tte)) &&
libinput_event_tablet_tool_get_proximity_state(tte) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT;
if (libinput_event_tablet_tool_get_proximity_state(tte) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_IN)
handleLibinputTabletToolAxis(e);
if (libinput_event_tablet_tool_get_proximity_state(tte) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT) {
if (!libinput_tablet_tool_is_unique(libinput_event_tablet_tool_get_tool(tte)) &&
libinput_event_tablet_tool_get_proximity_state(tte) == LIBINPUT_TABLET_TOOL_PROXIMITY_STATE_OUT)
std::erase(hlDevice->tabletTools, tool);
break;
}
// If this is proximity in, also process axis.
[[fallthrough]];
}
case LIBINPUT_EVENT_TABLET_TOOL_AXIS: {
handleLibinputTabletToolAxis(e);
break;
}
case LIBINPUT_EVENT_TABLET_TOOL_TIP: {
auto tte = libinput_event_get_tablet_tool_event(e);
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
handleLibinputTabletToolAxis(e);
hlDevice->tablet->events.tip.emit(ITablet::STipEvent{
.tool = tool,
.timeMs = (uint32_t)(libinput_event_tablet_tool_get_time_usec(tte) / 1000),
.absolute = {libinput_event_tablet_tool_get_x_transformed(tte, 1), libinput_event_tablet_tool_get_y_transformed(tte, 1)},
.down = libinput_event_tablet_tool_get_tip_state(tte) == LIBINPUT_TABLET_TOOL_TIP_DOWN,
});
break;
}
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: {
auto tte = libinput_event_get_tablet_tool_event(e);
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
handleLibinputTabletToolAxis(e);
hlDevice->tablet->events.button.emit(ITablet::SButtonEvent{
.tool = tool,
.timeMs = (uint32_t)(libinput_event_tablet_tool_get_time_usec(tte) / 1000),
.button = libinput_event_tablet_tool_get_button(tte),
.down = libinput_event_tablet_tool_get_button_state(tte) == LIBINPUT_BUTTON_STATE_PRESSED,
});
break;
}
default: break;
}
}
void Aquamarine::CSession::handleLibinputTabletToolAxis(libinput_event* e) {
auto device = libinput_event_get_device(e);
auto data = libinput_device_get_user_data(device);
auto hlDevice = ((CLibinputDevice*)data)->self.lock();
auto tte = libinput_event_get_tablet_tool_event(e);
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
@ -760,39 +797,6 @@ void Aquamarine::CSession::handleLibinputEvent(libinput_event* e) {
}
hlDevice->tablet->events.axis.emit(event);
if (destroyTool)
std::erase(hlDevice->tabletTools, tool);
break;
}
case LIBINPUT_EVENT_TABLET_TOOL_TIP: {
auto tte = libinput_event_get_tablet_tool_event(e);
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
hlDevice->tablet->events.tip.emit(ITablet::STipEvent{
.tool = tool,
.timeMs = (uint32_t)(libinput_event_tablet_tool_get_time_usec(tte) / 1000),
.absolute = {libinput_event_tablet_tool_get_x_transformed(tte, 1), libinput_event_tablet_tool_get_y_transformed(tte, 1)},
.down = libinput_event_tablet_tool_get_tip_state(tte) == LIBINPUT_TABLET_TOOL_TIP_DOWN,
});
break;
}
case LIBINPUT_EVENT_TABLET_TOOL_BUTTON: {
auto tte = libinput_event_get_tablet_tool_event(e);
auto tool = hlDevice->toolFrom(libinput_event_tablet_tool_get_tool(tte));
hlDevice->tablet->events.button.emit(ITablet::SButtonEvent{
.tool = tool,
.timeMs = (uint32_t)(libinput_event_tablet_tool_get_time_usec(tte) / 1000),
.button = libinput_event_tablet_tool_get_button(tte),
.down = libinput_event_tablet_tool_get_button_state(tte) == LIBINPUT_BUTTON_STATE_PRESSED,
});
break;
}
default: break;
}
}
Aquamarine::CLibinputDevice::CLibinputDevice(libinput_device* device_, Hyprutils::Memory::CWeakPointer<CSession> session_) : device(device_), session(session_) {