Skip to content

Commit

Permalink
input-manager: Refactor so new input devices don't refresh all mappings
Browse files Browse the repository at this point in the history
Before, hotplugging a new device would refresh all input to output mappings.
Hotplugging an output will still refresh all input device mappings.
  • Loading branch information
soreau committed Nov 6, 2024
1 parent 6e18861 commit bb729f4
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 37 deletions.
2 changes: 1 addition & 1 deletion src/core/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,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
74 changes: 39 additions & 35 deletions src/core/seat/input-manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,45 @@ 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(wlr_input_device *dev)
{
auto cursor = wf::get_core().get_wlr_cursor();
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);
}
}

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 +99,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->get_wlr_handle());
}
}

Expand Down Expand Up @@ -170,7 +174,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(wlr_input_device *dev);

/**
* 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

0 comments on commit bb729f4

Please sign in to comment.