Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input device updates #2510

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pixman = dependency('pixman-1')
xkbcommon = dependency('xkbcommon')
libdl = meson.get_compiler('cpp').find_library('dl')
json = dependency('nlohmann_json', version: '>= 3.11.2')
udev = dependency('libudev')

# We're not to use system wlroots: So we'll use the subproject
if get_option('use_system_wlroots').disabled()
Expand Down
2 changes: 1 addition & 1 deletion src/api/wayfire/config-backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class config_backend_t
* described in input-device.xml
*/
virtual std::shared_ptr<config::section_t> get_input_device_section(
wlr_input_device *device);
std::string const & prefix, wlr_input_device *device);
soreau marked this conversation as resolved.
Show resolved Hide resolved

virtual ~config_backend_t() = default;

Expand Down
26 changes: 14 additions & 12 deletions src/api/wayfire/debug.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,31 @@ namespace log
enum class logging_category : size_t
{
// Transactions - general
TXN = 0,
TXN = 0,
// Transactions - individual objects
TXNI = 1,
TXNI = 1,
// Views - events
VIEWS = 2,
VIEWS = 2,
// Wlroots messages
WLR = 3,
WLR = 3,
// Direct scanout
SCANOUT = 4,
SCANOUT = 4,
// Pointer events
POINTER = 5,
POINTER = 5,
// Workspace set events
WSET = 6,
WSET = 6,
// Keyboard-related events
KBD = 7,
KBD = 7,
// Xwayland-related events
XWL = 8,
XWL = 8,
// Layer-shell-related events
LSHELL = 9,
LSHELL = 9,
// Input-Method-related events
IM = 10,
IM = 10,
// Rendering-related events
RENDER = 11,
RENDER = 11,
// Input-device-related events
INPUT_DEVICES = 12,
TOTAL,
};

Expand Down
6 changes: 6 additions & 0 deletions src/api/wayfire/input-device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ class input_device_t
*/
bool set_enabled(bool enabled = true);

/**
* Calibrate a touch device with a matrix. This function does nothing
* if called with a device that is not a touch device.
*/
void calibrate_touch_device(std::string const & cal);

soreau marked this conversation as resolved.
Show resolved Hide resolved
/**
* @return true if the compositor should receive events from the device
*/
Expand Down
2 changes: 1 addition & 1 deletion src/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void wf::compositor_core_impl_t::post_init()
seat->focus_output(wo);

// Refresh device mappings when we have all outputs and devices
input->refresh_device_mappings();
input->configure_input_devices();

// Start processing cursor events
seat->priv->cursor->setup_listeners();
Expand Down
66 changes: 60 additions & 6 deletions src/core/plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "wayfire/signal-definitions.hpp"
#include <wayfire/util/log.hpp>
#include <wayfire/config-backend.hpp>
#include <libudev.h>

void wf::plugin_interface_t::fini()
{}
Expand All @@ -27,18 +28,71 @@ std::shared_ptr<config::section_t> wf::config_backend_t::get_output_section(
return config.get_section(name);
}

static struct udev_property_and_desc
{
char const *property_name;
char const *description;
} properties_and_descs[] =
{
{"ID_PATH", "stable physical connection path"},
{"ID_SERIAL", "stable vendor+pn+sn info"},
{"LIBINPUT_DEVICE_GROUP", "stable libinput info"},
// sometimes it contains info "by path", sometimes "by id"
{"DEVPATH", "unstable devpath"},
// used for debugging, to find DEVPATH and match the right
// device in `udevadm info --tree`
};

std::shared_ptr<config::section_t> wf::config_backend_t::get_input_device_section(
wlr_input_device *device)
std::string const & prefix, wlr_input_device *device)
{
std::string name = nonull(device->name);
name = "input-device:" + name;
auto& config = wf::get_core().config;
if (!config.get_section(name))
std::shared_ptr<wf::config::section_t> section;

if (wlr_input_device_is_libinput(device))
{
config.merge_section(
config.get_section("input-device")->clone_with_name(name));
auto libinput_dev = wlr_libinput_get_device_handle(device);
if (libinput_dev)
{
udev_device *udev_dev = libinput_device_get_udev_device(libinput_dev);
if (udev_dev)
{
for (struct udev_property_and_desc const & pd : properties_and_descs)
{
const char *value = udev_device_get_property_value(udev_dev, pd.property_name);
if (value == nullptr)
{
continue;
}

std::string name = prefix + ":" + nonull(value);
LOGC(INPUT_DEVICES, "Checking for config section [", name, "] ",
pd.property_name, " (", pd.description, ")");
section = config.get_section(name);
if (section)
{
LOGC(INPUT_DEVICES, "Using config section [", name, "] for ", nonull(device->name));
return section;
}
}
}
}
}

std::string name = nonull(device->name);
name = prefix + ":" + name;
LOGC(INPUT_DEVICES, "Checking for config section [", name, "]");
section = config.get_section(name);
if (section)
{
LOGC(INPUT_DEVICES, "Using config section [", name, "]");
return section;
}

config.merge_section(
config.get_section(prefix)->clone_with_name(name));

LOGC(INPUT_DEVICES, "Using config section [", name, "]");
return config.get_section(name);
}

Expand Down
83 changes: 46 additions & 37 deletions src/core/seat/input-manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,52 @@ void wf::input_manager_t::handle_new_input(wlr_input_device *dev)
data.device = nonstd::make_observer(input_devices.back().get());
wf::get_core().emit(&data);

refresh_device_mappings();
configure_input_devices();
}

void wf::input_manager_t::refresh_device_mappings()
void wf::input_manager_t::configure_input_device(std::unique_ptr<wf::input_device_impl_t> & device)
{
auto dev = device->get_wlr_handle();
auto cursor = wf::get_core().get_wlr_cursor();
auto section =
wf::get_core().config_backend->get_input_device_section("input-device", dev);

auto mapped_output = section->get_option("output")->get_value_str();
if (mapped_output.empty())
{
if (dev->type == WLR_INPUT_DEVICE_POINTER)
{
mapped_output = nonull(wlr_pointer_from_input_device(
dev)->output_name);
} else if (dev->type == WLR_INPUT_DEVICE_TOUCH)
{
mapped_output =
nonull(wlr_touch_from_input_device(dev)->output_name);
} else
{
mapped_output = nonull(dev->name);
}
}

auto cal = section->get_option("calibration")->get_value_str();
if (!cal.empty())
{
device->calibrate_touch_device(cal);
}

auto wo = wf::get_core().output_layout->find_output(mapped_output);
if (wo)
{
LOGD("Mapping input ", dev->name, " to output ", wo->to_string(), ".");
soreau marked this conversation as resolved.
Show resolved Hide resolved
wlr_cursor_map_input_to_output(cursor, dev, wo->handle);
} else
{
LOGD("Mapping input ", dev->name, " to output null.");
wlr_cursor_map_input_to_output(cursor, dev, nullptr);
}
}

void wf::input_manager_t::configure_input_devices()
{
// Might trigger motion events which we want to avoid at other stages
auto state = wf::get_core().get_current_state();
Expand All @@ -64,40 +106,9 @@ void wf::input_manager_t::refresh_device_mappings()
return;
}

auto cursor = wf::get_core().get_wlr_cursor();
for (auto& device : this->input_devices)
{
wlr_input_device *dev = device->get_wlr_handle();
auto section =
wf::get_core().config_backend->get_input_device_section(dev);

auto mapped_output = section->get_option("output")->get_value_str();
if (mapped_output.empty())
{
if (dev->type == WLR_INPUT_DEVICE_POINTER)
{
mapped_output = nonull(wlr_pointer_from_input_device(
dev)->output_name);
} else if (dev->type == WLR_INPUT_DEVICE_TOUCH)
{
mapped_output =
nonull(wlr_touch_from_input_device(dev)->output_name);
} else
{
mapped_output = nonull(dev->name);
}
}

auto wo = wf::get_core().output_layout->find_output(mapped_output);
if (wo)
{
LOGD("Mapping input ", dev->name, " to output ", wo->to_string(), ".");
wlr_cursor_map_input_to_output(cursor, dev, wo->handle);
} else
{
LOGD("Mapping input ", dev->name, " to output null.");
wlr_cursor_map_input_to_output(cursor, dev, nullptr);
}
configure_input_device(device);
}
}

Expand Down Expand Up @@ -141,8 +152,6 @@ void load_locked_mods_from_config(xkb_mod_mask_t& locked_mods)

wf::input_manager_t::input_manager_t()
{
wf::pointing_device_t::config.load();

load_locked_mods_from_config(locked_mods);

input_device_created.set_callback([&] (void *data)
Expand Down Expand Up @@ -170,7 +179,7 @@ wf::input_manager_t::input_manager_t()
ev->output->set_inhibited(true);
}

refresh_device_mappings();
configure_input_devices();
});
wf::get_core().output_layout->connect(&output_added);
}
Expand Down
8 changes: 7 additions & 1 deletion src/core/seat/input-manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ class input_manager_t
*/
uint32_t locked_mods = 0;

/**
* Map a single input device to output as specified in the
* config file or by hints in the wlroots backend.
*/
void configure_input_device(std::unique_ptr<wf::input_device_impl_t> & device);

/**
* Go through all input devices and map them to outputs as specified in the
* config file or by hints in the wlroots backend.
*/
void refresh_device_mappings();
void configure_input_devices();

input_manager_t();
~input_manager_t() = default;
Expand Down
20 changes: 12 additions & 8 deletions src/core/seat/keyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,18 @@ void wf::keyboard_t::setup_listeners()
wf::keyboard_t::keyboard_t(wlr_input_device *dev) :
handle(wlr_keyboard_from_input_device(dev)), device(dev)
{
model.load_option("input/xkb_model");
variant.load_option("input/xkb_variant");
layout.load_option("input/xkb_layout");
options.load_option("input/xkb_options");
rules.load_option("input/xkb_rules");

repeat_rate.load_option("input/kb_repeat_rate");
repeat_delay.load_option("input/kb_repeat_delay");
auto section =
soreau marked this conversation as resolved.
Show resolved Hide resolved
wf::get_core().config_backend->get_input_device_section("input", dev);
auto section_name = section->get_name();

model.load_option(section_name + "/xkb_model");
variant.load_option(section_name + "/xkb_variant");
layout.load_option(section_name + "/xkb_layout");
options.load_option(section_name + "/xkb_options");
rules.load_option(section_name + "/xkb_rules");

repeat_rate.load_option(section_name + "/kb_repeat_rate");
repeat_delay.load_option(section_name + "/kb_repeat_delay");

// When the configuration options change, mark them as dirty.
// They are applied at the config-reloaded signal.
Expand Down
5 changes: 2 additions & 3 deletions src/core/seat/pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,8 @@ void wf::pointer_t::handle_pointer_axis(wlr_pointer_axis_event *ev,
}

/* Calculate speed settings */
double mult = ev->source == WL_POINTER_AXIS_SOURCE_FINGER ?
wf::pointing_device_t::config.touchpad_scroll_speed :
wf::pointing_device_t::config.mouse_scroll_speed;
wf::pointing_device_t *pd = (wf::pointing_device_t*)ev->pointer->base.data;
double mult = pd->get_scroll_speed(&ev->pointer->base, ev->source == WL_POINTER_AXIS_SOURCE_FINGER);

ev->delta *= mult;
ev->delta_discrete *= mult;
Expand Down
Loading
Loading