aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/input/libinput.c23
-rw-r--r--sway/input/seat.c49
-rw-r--r--sway/meson.build1
3 files changed, 73 insertions, 0 deletions
diff --git a/sway/input/libinput.c b/sway/input/libinput.c
index 54520f9e..060a584a 100644
--- a/sway/input/libinput.c
+++ b/sway/input/libinput.c
@@ -1,5 +1,6 @@
#include <float.h>
#include <libinput.h>
+#include <libudev.h>
#include <limits.h>
#include <wlr/backend/libinput.h>
#include "log.h"
@@ -312,3 +313,25 @@ void sway_input_reset_libinput_device(struct sway_input_device *input_device) {
ipc_event_input("libinput_config", input_device);
}
}
+
+bool sway_libinput_device_is_builtin(struct sway_input_device *sway_device) {
+ if (!wlr_input_device_is_libinput(sway_device->wlr_device)) {
+ return false;
+ }
+
+ struct libinput_device *device =
+ wlr_libinput_get_device_handle(sway_device->wlr_device);
+ struct udev_device *udev_device =
+ libinput_device_get_udev_device(device);
+ if (!udev_device) {
+ return false;
+ }
+
+ const char *id_path = udev_device_get_property_value(udev_device, "ID_PATH");
+ if (!id_path) {
+ return false;
+ }
+
+ const char prefix[] = "platform-";
+ return strncmp(id_path, prefix, strlen(prefix)) == 0;
+}
diff --git a/sway/input/seat.c b/sway/input/seat.c
index e6e1d4fb..d23525a8 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -20,6 +20,7 @@
#include "sway/input/cursor.h"
#include "sway/input/input-manager.h"
#include "sway/input/keyboard.h"
+#include "sway/input/libinput.h"
#include "sway/input/seat.h"
#include "sway/input/switch.h"
#include "sway/input/tablet.h"
@@ -666,6 +667,40 @@ static void seat_reset_input_config(struct sway_seat *seat,
sway_device->input_device->wlr_device, NULL);
}
+static bool has_prefix(const char *str, const char *prefix) {
+ return strncmp(str, prefix, strlen(prefix)) == 0;
+}
+
+/**
+ * Get the name of the built-in output, if any. Returns NULL if there isn't
+ * exactly one built-in output.
+ */
+static const char *get_builtin_output_name(void) {
+ const char *match = NULL;
+ for (int i = 0; i < root->outputs->length; ++i) {
+ struct sway_output *output = root->outputs->items[i];
+ const char *name = output->wlr_output->name;
+ if (has_prefix(name, "eDP-") || has_prefix(name, "LVDS-") ||
+ has_prefix(name, "DSI-")) {
+ if (match != NULL) {
+ return NULL;
+ }
+ match = name;
+ }
+ }
+ return match;
+}
+
+static bool is_touch_or_tablet_tool(struct sway_seat_device *seat_device) {
+ switch (seat_device->input_device->wlr_device->type) {
+ case WLR_INPUT_DEVICE_TOUCH:
+ case WLR_INPUT_DEVICE_TABLET_TOOL:
+ return true;
+ default:
+ return false;
+ }
+}
+
static void seat_apply_input_config(struct sway_seat *seat,
struct sway_seat_device *sway_device) {
struct input_config *ic =
@@ -681,7 +716,21 @@ static void seat_apply_input_config(struct sway_seat *seat,
switch (mapped_to) {
case MAPPED_TO_DEFAULT:
+ /*
+ * If the wlroots backend provides an output name, use that.
+ *
+ * Otherwise, try to map built-in touch and tablet tool devices to the
+ * built-in output.
+ */
mapped_to_output = sway_device->input_device->wlr_device->output_name;
+ if (mapped_to_output == NULL && is_touch_or_tablet_tool(sway_device) &&
+ sway_libinput_device_is_builtin(sway_device->input_device)) {
+ mapped_to_output = get_builtin_output_name();
+ if (mapped_to_output) {
+ sway_log(SWAY_DEBUG, "Auto-detected output '%s' for device '%s'",
+ mapped_to_output, sway_device->input_device->identifier);
+ }
+ }
if (mapped_to_output == NULL) {
return;
}
diff --git a/sway/meson.build b/sway/meson.build
index f163ee90..b52fada4 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -208,6 +208,7 @@ sway_deps = [
jsonc,
libevdev,
libinput,
+ libudev,
math,
pango,
pcre,