diff --git a/include/config/rcxml.h b/include/config/rcxml.h index f27e4836..2dbb2096 100644 --- a/include/config/rcxml.h +++ b/include/config/rcxml.h @@ -4,9 +4,9 @@ #include #include #include -#include #include "common/buf.h" +#include "config/libinput.h" struct rcxml { bool xdg_shell_server_side_deco; @@ -22,13 +22,7 @@ struct rcxml { struct wl_list keybinds; struct wl_list mousebinds; long doubleclick_time; /* in ms */ - float pointer_speed; - int natural_scroll; - int left_handed; - enum libinput_config_tap_state tap; - enum libinput_config_accel_profile accel_profile; - enum libinput_config_middle_emulation_state middle_emu; - enum libinput_config_dwt_state dwt; + struct wl_list libinput_categories; int repeat_rate; int repeat_delay; }; diff --git a/src/config/libinput.c b/src/config/libinput.c new file mode 100644 index 00000000..e8ce4cfd --- /dev/null +++ b/src/config/libinput.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include + +#include "config/libinput.h" +#include "config/rcxml.h" +static void +libinput_category_init(struct libinput_category *l) +{ + l->name = NULL; + l->pointer_speed = -2; + l->natural_scroll = -1; + l->left_handed = -1; + l->tap = LIBINPUT_CONFIG_TAP_ENABLED; + l->accel_profile = -1; + l->middle_emu = -1; + l->dwt = -1; +} + +enum device_type +get_device_type(const char *s) +{ + if (!s) { + return DEFAULT_DEVICE; + } + if (!strcasecmp(s, "touch")) { + return TOUCH_DEVICE; + } + if (!strcasecmp(s, "non-touch")) { + return NON_TOUCH_DEVICE; + } + return DEFAULT_DEVICE; +} + +struct libinput_category * +libinput_category_create() +{ + struct libinput_category *l = calloc(1, sizeof(struct libinput_category)); + if (!l) { + return NULL; + } + libinput_category_init(l); + wl_list_insert(&rc.libinput_categories, &l->link); + return l; +} diff --git a/src/config/meson.build b/src/config/meson.build index b5dcf50b..95afc7bc 100644 --- a/src/config/meson.build +++ b/src/config/meson.build @@ -3,4 +3,5 @@ labwc_sources += files( 'keybind.c', 'session.c', 'mousebind.c', + 'libinput.c', ) diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 29dbb79b..c9933d51 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -18,13 +18,16 @@ #include "common/string-helpers.h" #include "common/zfree.h" #include "config/keybind.h" +#include "config/libinput.h" #include "config/mousebind.h" #include "config/rcxml.h" static bool in_keybind; static bool in_mousebind; +static bool in_libinput_category; static struct keybind *current_keybind; static struct mousebind *current_mousebind; +static struct libinput_category *current_libinput_category; static const char *current_mouse_context; enum font_place { @@ -128,6 +131,61 @@ get_accel_profile(const char *s) return LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; } +static void +fill_libinput_category(char *nodename, char *content) +{ + + if (!strcmp(nodename, "category.device.libinput")) { + current_libinput_category = libinput_category_create(); + } + + if (!content) { + return; + } + + if (!current_libinput_category) { + return; + } + + string_truncate_at_pattern(nodename, ".device.libinput"); + + if (!strcmp(nodename, "category")) { + if (!strcmp(content, "touch") + || !strcmp(content, "non-touch") + || !strcmp(content, "default")) { + current_libinput_category->type = get_device_type(content); + } else { + current_libinput_category->name = strdup(content); + } + } else if (!strcasecmp(nodename, "naturalscroll")) { + current_libinput_category->natural_scroll = + get_bool(content) ? 1 : 0; + } else if (!strcasecmp(nodename, "lefthanded")) { + current_libinput_category->left_handed = get_bool(content) ? 1 : 0; + } else if (!strcmp(nodename, "pointerspeed")) { + current_libinput_category->pointer_speed = atof(content); + if (current_libinput_category->pointer_speed < -1) { + current_libinput_category->pointer_speed = -1; + } else if (current_libinput_category->pointer_speed > 1) { + current_libinput_category->pointer_speed = 1; + } + } else if (!strcasecmp(nodename, "tap")) { + current_libinput_category->tap = get_bool(content) ? + LIBINPUT_CONFIG_TAP_ENABLED : + LIBINPUT_CONFIG_TAP_DISABLED; + } else if (!strcasecmp(nodename, "accelprofile")) { + current_libinput_category->accel_profile = get_accel_profile(content); + } else if (!strcasecmp(nodename, "middleemulation")) { + current_libinput_category->middle_emu = get_bool(content) ? + LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED : + LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; + } else if (!strcasecmp(nodename, "disablewhiletyping")) { + current_libinput_category->dwt = get_bool(content) ? + LIBINPUT_CONFIG_DWT_ENABLED : + LIBINPUT_CONFIG_DWT_DISABLED; + } +} + static void fill_font(char *nodename, char *content, enum font_place place) { @@ -208,6 +266,9 @@ entry(xmlNode *node, char *nodename, char *content) if (in_mousebind) { fill_mousebind(nodename, content); } + if (in_libinput_category) { + fill_libinput_category(nodename, content); + } /* handle nodes without content, e.g. */ if (!strcmp(nodename, "default.keyboard")) { @@ -253,24 +314,6 @@ entry(xmlNode *node, char *nodename, char *content) } } else if (!strcasecmp(nodename, "name.context.mouse")) { current_mouse_context = content; - } else if (!strcasecmp(nodename, "PointerSpeed.libinput")) { - rc.pointer_speed = atof(content); - } else if (!strcasecmp(nodename, "NaturalScroll.libinput")) { - rc.natural_scroll = get_bool(content) ? 1 : 0; - } else if (!strcasecmp(nodename, "LeftHanded.libinput")) { - rc.left_handed = get_bool(content) ? 1 : 0; - } else if (!strcasecmp(nodename, "Tap.libinput")) { - rc.tap = get_bool(content) ? LIBINPUT_CONFIG_TAP_ENABLED : - LIBINPUT_CONFIG_TAP_DISABLED; - } else if (!strcasecmp(nodename, "MiddleEmulation.libinput")) { - rc.middle_emu = get_bool(content) ? - LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED : - LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED; - } else if (!strcasecmp(nodename, "DisableWhileTyping.libinput")) { - rc.dwt = get_bool(content) ? LIBINPUT_CONFIG_DWT_ENABLED : - LIBINPUT_CONFIG_DWT_DISABLED; - } else if (!strcasecmp(nodename, "AccelerationProfile.libinput")) { - rc.accel_profile = get_accel_profile(content); } else if (!strcasecmp(nodename, "RepeatRate.keyboard")) { rc.repeat_rate = atoi(content); } else if (!strcasecmp(nodename, "RepeatDelay.keyboard")) { @@ -324,6 +367,12 @@ xml_tree_walk(xmlNode *node) in_mousebind = false; continue; } + if (!strcasecmp((char *)n->name, "device")) { + in_libinput_category = true; + traverse(n); + in_libinput_category = false; + continue; + } traverse(n); } } @@ -354,18 +403,12 @@ rcxml_init() LIBXML_TEST_VERSION wl_list_init(&rc.keybinds); wl_list_init(&rc.mousebinds); + wl_list_init(&rc.libinput_categories); rc.xdg_shell_server_side_deco = true; rc.corner_radius = 8; rc.font_size_activewindow = 10; rc.font_size_menuitem = 10; rc.doubleclick_time = 500; - rc.pointer_speed = -2; - rc.natural_scroll = -1; - rc.left_handed = -1; - rc.tap = LIBINPUT_CONFIG_TAP_ENABLED; - rc.accel_profile = -1; - rc.middle_emu = -1; - rc.dwt = -1; rc.repeat_rate = 25; rc.repeat_delay = 600; } @@ -445,6 +488,11 @@ post_processing(void) if (!rc.font_name_menuitem) { rc.font_name_menuitem = strdup("sans"); } + if (!wl_list_length(&rc.libinput_categories)) { + /* So we still allow tap to click by default */ + struct libinput_category *l = libinput_category_create(); + l->type = TOUCH_DEVICE; + } } static void @@ -535,4 +583,11 @@ rcxml_finish(void) zfree(m->action); zfree(m); } + + struct libinput_category *l, *l_tmp; + wl_list_for_each_safe(l, l_tmp, &rc.libinput_categories, link) { + wl_list_remove(&l->link); + zfree(l->name); + zfree(l); + } } diff --git a/src/seat.c b/src/seat.c index 469ae96f..1f1a75bf 100644 --- a/src/seat.c +++ b/src/seat.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only #include +#include #include #include #include "labwc.h" @@ -15,10 +16,6 @@ input_device_destroy(struct wl_listener *listener, void *data) static void configure_libinput(struct wlr_input_device *wlr_input_device) { - /* - * We want to enable full libinput configuration eventually, but - * for the time being, lets just enable tap. - */ if (!wlr_input_device) { wlr_log(WLR_ERROR, "no wlr_input_device"); return; @@ -30,60 +27,86 @@ configure_libinput(struct wlr_input_device *wlr_input_device) return; } + enum device_type current_type; + if (wlr_input_device->width_mm) { + current_type = TOUCH_DEVICE; + } else { + current_type = NON_TOUCH_DEVICE; + } + + struct libinput_category *device_category, *dc = NULL; + wl_list_for_each(device_category, &rc.libinput_categories, link) { + if (device_category->name) { + if (!strcasecmp(wlr_input_device->name, device_category->name)) { + dc = device_category; + break; + } + } else if (device_category->type == current_type) { + dc = device_category; + } else if (device_category->type == DEFAULT_DEVICE && !dc) { + dc = device_category; + } + } + + if (!dc) { + wlr_log(WLR_INFO, "Skipping libinput configuration for device"); + return; + } + if (libinput_device_config_tap_get_finger_count(libinput_dev) <= 0) { wlr_log(WLR_INFO, "tap unavailable"); } else { wlr_log(WLR_INFO, "tap configured"); - libinput_device_config_tap_set_enabled(libinput_dev, rc.tap); + libinput_device_config_tap_set_enabled(libinput_dev, dc->tap); } if (libinput_device_config_scroll_has_natural_scroll(libinput_dev) <= 0 - || rc.natural_scroll < 0) { + || dc->natural_scroll < 0) { wlr_log(WLR_INFO, "natural scroll not configured"); } else { wlr_log(WLR_INFO, "natural scroll configured"); libinput_device_config_scroll_set_natural_scroll_enabled( - libinput_dev, rc.natural_scroll); + libinput_dev, dc->natural_scroll); } if (libinput_device_config_left_handed_is_available(libinput_dev) <= 0 - || rc.left_handed < 0) { + || dc->left_handed < 0) { wlr_log(WLR_INFO, "left-handed mode not configured"); } else { wlr_log(WLR_INFO, "left-handed mode configured"); libinput_device_config_left_handed_set(libinput_dev, - rc.left_handed); + dc->left_handed); } if (libinput_device_config_accel_is_available(libinput_dev) == 0) { wlr_log(WLR_INFO, "pointer acceleration unavailable"); } else { wlr_log(WLR_INFO, "pointer acceleration configured"); - if (rc.pointer_speed > -1) { + if (dc->pointer_speed > -1) { libinput_device_config_accel_set_speed(libinput_dev, - rc.pointer_speed); + dc->pointer_speed); } - if (rc.accel_profile > 0) { + if (dc->accel_profile > 0) { libinput_device_config_accel_set_profile(libinput_dev, - rc.accel_profile); + dc->accel_profile); } } if (libinput_device_config_middle_emulation_is_available(libinput_dev) - == 0 || rc.dwt < 0) { + == 0 || dc->middle_emu < 0) { wlr_log(WLR_INFO, "middle emulation not configured"); } else { wlr_log(WLR_INFO, "middle emulation configured"); libinput_device_config_middle_emulation_set_enabled( - libinput_dev, rc.middle_emu); + libinput_dev, dc->middle_emu); } if (libinput_device_config_dwt_is_available(libinput_dev) == 0 - || rc.dwt < 0) { + || dc->dwt < 0) { wlr_log(WLR_INFO, "dwt not configured"); } else { wlr_log(WLR_INFO, "dwt configured"); - libinput_device_config_dwt_set_enabled(libinput_dev, rc.dwt); + libinput_device_config_dwt_set_enabled(libinput_dev, dc->dwt); } }