Skip to content

events: add support for switch events#4948

Open
muhammad23012009 wants to merge 3 commits into
canonical:mainfrom
muhammad23012009:main
Open

events: add support for switch events#4948
muhammad23012009 wants to merge 3 commits into
canonical:mainfrom
muhammad23012009:main

Conversation

@muhammad23012009
Copy link
Copy Markdown
Contributor

  • currently these events are not handled by Mir itself. QtMir is the only user, with an event filter to steal these switch events.

What's new?

Adds support for processing switch events from libinput

Checklist

  • Tests added and pass
  • Adequate documentation added
  • (optional) Added Screenshots or videos

Copilot AI review requested due to automatic review settings May 17, 2026 21:28
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class handling of libinput “switch” events (e.g. tablet-mode toggles) to Mir, so these events can be converted into Mir input events and surfaced through the public toolkit API instead of being intercepted only by downstream consumers (e.g. QtMir).

Changes:

  • Introduces MirSwitchEvent plus new toolkit enums/accessors for switch action/state.
  • Extends the input event builder + event factory code to construct switch events and exports the new symbols.
  • Adds libinput evdev handling for LIBINPUT_EVENT_SWITCH_TOGGLE and threads the new input-event type through a few server components’ input-type switches.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
tests/unit-tests/input/evdev/test_libinput_device.cpp Extends the test event-builder mock for switch events (but no new switch tests yet).
src/server/shell/decoration/input.cpp Ignores switch input events in decoration input handling.
src/server/shell/abstract_shell.cpp Explicitly returns false for switch input events.
src/server/input/idle_poking_dispatcher.cpp Ensures switch events don’t poke the idle timer.
src/server/input/default_event_builder.h Adds switch_event() to DefaultEventBuilder.
src/server/input/default_event_builder.cpp Implements DefaultEventBuilder::switch_event().
src/server/frontend_xwayland/xwayland_surface_observer.cpp Treats switch events as non-move/resize events.
src/platforms/evdev/libinput_device.h Declares switch-event conversion method.
src/platforms/evdev/libinput_device.cpp Handles LIBINPUT_EVENT_SWITCH_TOGGLE and converts tablet-mode toggles.
src/common/symbols.map Exports new switch event C API + factory symbol.
src/common/input/input_event.cpp Adds switch input-type string + toolkit accessors for switch events.
src/common/events/switch_event.cpp Implements the new MirSwitchEvent type.
src/common/events/input_event.cpp Adds to_switch() casting helpers.
src/common/events/event_private.h Pulls in the new switch event definition for internal event plumbing.
src/common/events/event_builders.cpp Adds make_switch_event() factory.
src/common/events/CMakeLists.txt Builds the new switch_event.cpp.
include/platform/mir/input/event_builder.h Adds EventBuilder::switch_event() API.
include/core/mir_toolkit/events/enums.h Adds mir_input_event_type_switch and switch action/state enums.
include/common/mir/events/switch_event.h Adds internal C++ MirSwitchEvent header.
include/common/mir/events/input_event.h Adds to_switch() declarations.
include/common/mir/events/event_builders.h Declares make_switch_event() factory.
include/common/mir_toolkit/events/input/switch_event.h Adds toolkit header for switch event accessors.
include/common/mir_toolkit/events/input/input_event.h Exposes mir_input_event_get_switch_event() in the toolkit API.

Comment thread src/platforms/evdev/libinput_device.cpp Outdated
Comment on lines +372 to +385
mir::EventUPtr mie::LibInputDevice::convert_switch_event(libinput_event_switch* switch_event)
{
auto const libinput_switch_type = libinput_event_switch_get_switch(switch_event);
auto const libinput_switch_state = libinput_event_switch_get_switch_state(switch_event);

switch (libinput_switch_type)
{
case LIBINPUT_SWITCH_TABLET_MODE:
return builder->switch_event(
mir_switch_action_tablet_mode,
libinput_switch_state == LIBINPUT_SWITCH_STATE_ON ? mir_switch_state_on : mir_switch_state_off);
default:
return {nullptr, [](auto){}};
}
std::optional<Timestamp> timestamp,
std::vector<mir::events::TouchContact> const& contacts) = 0;

virtual EventUPtr switch_event(
Comment on lines +375 to +385
mir::EventUPtr mev::make_switch_event(
MirInputDeviceId device_id,
MirSwitchAction action,
MirSwitchState state)
{
auto e = new_event<MirSwitchEvent>(device_id);
e->set_action(action);
e->set_state(state);

return make_uptr_event(e);
}
Comment on lines +260 to +264
if(ev->input_type() != mir_input_event_type_switch)
{
mir::fatal_error_abort("expected switch input event but event was of type ",
input_event_type_to_c_str(ev->input_type()));
}
Comment on lines +1 to +5
#ifndef MIR_COMMON_SWITCH_EVENT_H_
#define MIR_COMMON_SWITCH_EVENT_H_

#include <mir/events/input_event.h>

Comment on lines +1 to +5
#ifndef MIR_TOOLKIT_SWITCH_EVENT_H_
#define MIR_TOOLKIT_SWITCH_EVENT_H_

#include <mir_toolkit/events/input/input_event.h>

Comment on lines +1 to +3
#include <mir/events/input_event.h>
#include <mir/events/switch_event.h>

BOOST_THROW_EXCEPTION(std::logic_error("deprecated event builder method called"));
}

MOCK_METHOD(mir::EventUPtr, switch_event, (MirSwitchAction, MirSwitchState), ());
Comment on lines +192 to +193
MirSwitchAction action,
MirSwitchState state);
Copy link
Copy Markdown
Contributor

@AlanGriffiths AlanGriffiths left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The approach looks sensible.

Copilot has identified a bunch of housekeeping (missing license headers, builder parameters etc). These need addressing. (Technically, copyright doesn't need to be assigned to Canonical as long as the CLA is in place.)

This does involve ABI breakages, so we also need to bump .sonames etc. (but the Mir team can deal with that separately.)

There are, however, parallel APIs in libmiral (include/miral/miral/toolkit_event.h) and, potentially, libmiroil (include/miroil/miroil/input_device.h) that need to reflect these changes.

Comment thread include/common/mir/events/input_event.h Outdated
mir_input_event_type_touch = 1,
mir_input_event_type_pointer = 2,
mir_input_event_type_keyboard_resync = 3,
mir_input_event_type_switch = 4,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FLAGGING FOR ATTENTION: Extending this switch is an ABI break: downstream code needs to be recompiled. (That's not blocking this PR, but we need to do deal with it before a release.)

std::optional<Timestamp> timestamp,
std::vector<mir::events::TouchContact> const& contacts) = 0;

virtual EventUPtr switch_event(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FLAGGING FOR ATTENTION: Adding a virtual function to this interface is an ABI break: downstream code needs to be recompiled and implement this function. (That's not blocking this PR, but we need to do deal with it before a release.)

Note also: as we're breaking ABI, there's a bunch of [[deprecated]] functions we can get rid of.

muhammad23012009 and others added 3 commits May 21, 2026 14:41
* currently these events are not handled by Mir itself. QtMir is the
  only user, with an event filter to steal these switch events.

Signed-off-by: Muhammad <thevancedgamer@mentallysanemainliners.org>
Signed-off-by: Muhammad <thevancedgamer@mentallysanemainliners.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants