From 4696f49ecc69aa86ea6bd53fc08abf6a32b4a414 Mon Sep 17 00:00:00 2001
From: Brian Ashworth <bosrsf04@gmail.com>
Date: Wed, 9 Jan 2019 00:09:20 -0500
Subject: reload: reset input configs

This resets all input options to their defaults on reload. This also
fixes some debug log typos in `input_manager_libinput_config_pointer`.
---
 include/sway/input/input-manager.h |   4 +
 include/sway/input/seat.h          |   3 +
 sway/config.c                      |   2 +
 sway/input/input-manager.c         | 172 ++++++++++++++++++++++++++++++++++++-
 sway/input/seat.c                  |  37 ++++++++
 5 files changed, 215 insertions(+), 3 deletions(-)

diff --git a/include/sway/input/input-manager.h b/include/sway/input/input-manager.h
index 08e749dc..8e8bf1f2 100644
--- a/include/sway/input/input-manager.h
+++ b/include/sway/input/input-manager.h
@@ -37,6 +37,10 @@ void input_manager_configure_xcursor(void);
 
 void input_manager_apply_input_config(struct input_config *input_config);
 
+void input_manager_reset_input(struct sway_input_device *input_device);
+
+void input_manager_reset_all_inputs();
+
 void input_manager_apply_seat_config(struct seat_config *seat_config);
 
 struct sway_seat *input_manager_get_default_seat(void);
diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h
index a3c20346..c10b48b1 100644
--- a/include/sway/input/seat.h
+++ b/include/sway/input/seat.h
@@ -100,6 +100,9 @@ void seat_add_device(struct sway_seat *seat,
 void seat_configure_device(struct sway_seat *seat,
 		struct sway_input_device *device);
 
+void seat_reset_device(struct sway_seat *seat,
+		struct sway_input_device *input_device);
+
 void seat_remove_device(struct sway_seat *seat,
 		struct sway_input_device *device);
 
diff --git a/sway/config.c b/sway/config.c
index f99f043c..cd0857f4 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -387,6 +387,8 @@ bool load_main_config(const char *file, bool is_active, bool validating) {
 		memcpy(&config->swaynag_config_errors,
 				&old_config->swaynag_config_errors,
 				sizeof(struct swaynag_instance));
+
+		input_manager_reset_all_inputs();
 	}
 
 	config->current_config_path = path;
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index 04e14355..d90803f6 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -129,6 +129,24 @@ static void input_manager_libinput_config_keyboard(
 	}
 }
 
+static void input_manager_libinput_reset_keyboard(
+		struct sway_input_device *input_device) {
+	struct wlr_input_device *wlr_device = input_device->wlr_device;
+	struct libinput_device *libinput_device;
+
+	if (!wlr_input_device_is_libinput(wlr_device)) {
+		return;
+	}
+
+	libinput_device = wlr_libinput_get_device_handle(wlr_device);
+
+	uint32_t send_events =
+		libinput_device_config_send_events_get_default_mode(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_keyboard(%s) send_events_set_mode(%d)",
+		input_device->identifier, send_events);
+	libinput_device_config_send_events_set_mode(libinput_device, send_events);
+}
+
 static void input_manager_libinput_config_touch(
 		struct sway_input_device *input_device) {
 	struct wlr_input_device *wlr_device = input_device->wlr_device;
@@ -151,6 +169,24 @@ static void input_manager_libinput_config_touch(
 	}
 }
 
+static void input_manager_libinput_reset_touch(
+		struct sway_input_device *input_device) {
+	struct wlr_input_device *wlr_device = input_device->wlr_device;
+	struct libinput_device *libinput_device;
+
+	if (!wlr_input_device_is_libinput(wlr_device)) {
+		return;
+	}
+
+	libinput_device = wlr_libinput_get_device_handle(wlr_device);
+
+	uint32_t send_events =
+		libinput_device_config_send_events_get_default_mode(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_touch(%s) send_events_set_mode(%d)",
+		input_device->identifier, send_events);
+	libinput_device_config_send_events_set_mode(libinput_device, send_events);
+}
+
 static void input_manager_libinput_config_pointer(
 		struct sway_input_device *input_device) {
 	struct wlr_input_device *wlr_device = input_device->wlr_device;
@@ -180,14 +216,14 @@ static void input_manager_libinput_config_pointer(
 	if (ic->drag != INT_MIN) {
 		wlr_log(WLR_DEBUG,
 			"libinput_config_pointer(%s) tap_set_drag_enabled(%d)",
-			ic->identifier, ic->click_method);
+			ic->identifier, ic->drag);
 		libinput_device_config_tap_set_drag_enabled(libinput_device,
 			ic->drag);
 	}
 	if (ic->drag_lock != INT_MIN) {
 		wlr_log(WLR_DEBUG,
 			"libinput_config_pointer(%s) tap_set_drag_lock_enabled(%d)",
-			ic->identifier, ic->click_method);
+			ic->identifier, ic->drag_lock);
 		libinput_device_config_tap_set_drag_lock_enabled(libinput_device,
 			ic->drag_lock);
 	}
@@ -248,12 +284,118 @@ static void input_manager_libinput_config_pointer(
 	}
 	if (ic->tap_button_map != INT_MIN) {
 		wlr_log(WLR_DEBUG, "libinput_config_pointer(%s) tap_set_button_map(%d)",
-			ic->identifier, ic->tap);
+			ic->identifier, ic->tap_button_map);
 		libinput_device_config_tap_set_button_map(libinput_device,
 			ic->tap_button_map);
 	}
 }
 
+static void input_manager_libinput_reset_pointer(
+		struct sway_input_device *input_device) {
+	struct wlr_input_device *wlr_device = input_device->wlr_device;
+
+	if (!wlr_input_device_is_libinput(wlr_device)) {
+		return;
+	}
+
+	struct libinput_device *libinput_device =
+		wlr_libinput_get_device_handle(wlr_device);
+
+	enum libinput_config_accel_profile accel_profile =
+		libinput_device_config_accel_get_default_profile(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) accel_set_profile(%d)",
+			input_device->identifier, accel_profile);
+	libinput_device_config_accel_set_profile(libinput_device, accel_profile);
+
+	enum libinput_config_click_method click_method =
+		libinput_device_config_click_get_default_method(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) click_set_method(%d)",
+		input_device->identifier, click_method);
+	libinput_device_config_click_set_method(libinput_device, click_method);
+
+	enum libinput_config_drag_state drag =
+		libinput_device_config_tap_get_default_drag_enabled(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) tap_set_drag_enabled(%d)",
+			input_device->identifier, drag);
+	libinput_device_config_tap_set_drag_enabled(libinput_device, drag);
+
+	enum libinput_config_drag_lock_state drag_lock =
+		libinput_device_config_tap_get_default_drag_lock_enabled(
+				libinput_device);
+	wlr_log(WLR_DEBUG,
+			"libinput_reset_pointer(%s) tap_set_drag_lock_enabled(%d)",
+			input_device->identifier, drag_lock);
+	libinput_device_config_tap_set_drag_lock_enabled(libinput_device,
+			drag_lock);
+
+	enum libinput_config_dwt_state dwt =
+		libinput_device_config_dwt_get_default_enabled(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) dwt_set_enabled(%d)",
+		input_device->identifier, dwt);
+	libinput_device_config_dwt_set_enabled(libinput_device, dwt);
+
+	int left_handed =
+		libinput_device_config_left_handed_get_default(libinput_device);
+	wlr_log(WLR_DEBUG,
+		"libinput_reset_pointer(%s) left_handed_set_enabled(%d)",
+		input_device->identifier, left_handed);
+	libinput_device_config_left_handed_set(libinput_device, left_handed);
+
+	enum libinput_config_middle_emulation_state middle_emulation =
+		libinput_device_config_middle_emulation_get_default_enabled(
+				libinput_device);
+	wlr_log(WLR_DEBUG,
+		"libinput_reset_pointer(%s) middle_emulation_set_enabled(%d)",
+		input_device->identifier, middle_emulation);
+	libinput_device_config_middle_emulation_set_enabled(libinput_device,
+		middle_emulation);
+
+	int natural_scroll =
+		libinput_device_config_scroll_get_default_natural_scroll_enabled(
+				libinput_device);
+	wlr_log(WLR_DEBUG,
+		"libinput_reset_pointer(%s) natural_scroll_set_enabled(%d)",
+		input_device->identifier, natural_scroll);
+	libinput_device_config_scroll_set_natural_scroll_enabled(
+		libinput_device, natural_scroll);
+
+	double pointer_accel =
+		libinput_device_config_accel_get_default_speed(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) accel_set_speed(%f)",
+		input_device->identifier, pointer_accel);
+	libinput_device_config_accel_set_speed(libinput_device, pointer_accel);
+
+	uint32_t scroll_button =
+		libinput_device_config_scroll_get_default_button(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) scroll_set_button(%d)",
+		input_device->identifier, scroll_button);
+	libinput_device_config_scroll_set_button(libinput_device, scroll_button);
+
+	enum libinput_config_scroll_method scroll_method =
+		libinput_device_config_scroll_get_default_method(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) scroll_set_method(%d)",
+		input_device->identifier, scroll_method);
+	libinput_device_config_scroll_set_method(libinput_device, scroll_method);
+
+	uint32_t send_events =
+		libinput_device_config_send_events_get_default_mode(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) send_events_set_mode(%d)",
+		input_device->identifier, send_events);
+	libinput_device_config_send_events_set_mode(libinput_device, send_events);
+
+	enum libinput_config_tap_state tap =
+		libinput_device_config_tap_get_default_enabled(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) tap_set_enabled(%d)",
+		input_device->identifier, tap);
+	libinput_device_config_tap_set_enabled(libinput_device, tap);
+
+	enum libinput_config_tap_button_map tap_button_map =
+		libinput_device_config_tap_get_button_map(libinput_device);
+	wlr_log(WLR_DEBUG, "libinput_reset_pointer(%s) tap_set_button_map(%d)",
+		input_device->identifier, tap_button_map);
+	libinput_device_config_tap_set_button_map(libinput_device, tap_button_map);
+}
+
 static void handle_device_destroy(struct wl_listener *listener, void *data) {
 	struct wlr_input_device *device = data;
 
@@ -466,6 +608,30 @@ void input_manager_apply_input_config(struct input_config *input_config) {
 	}
 }
 
+void input_manager_reset_input(struct sway_input_device *input_device) {
+	if (input_device->wlr_device->type == WLR_INPUT_DEVICE_POINTER ||
+			input_device->wlr_device->type == WLR_INPUT_DEVICE_TABLET_TOOL) {
+		input_manager_libinput_reset_pointer(input_device);
+	} else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
+		input_manager_libinput_reset_keyboard(input_device);
+	} else if (input_device->wlr_device->type == WLR_INPUT_DEVICE_TOUCH) {
+		input_manager_libinput_reset_touch(input_device);
+	}
+
+	struct sway_seat *seat = NULL;
+	wl_list_for_each(seat, &server.input->seats, link) {
+		seat_reset_device(seat, input_device);
+	}
+}
+
+void input_manager_reset_all_inputs() {
+	struct sway_input_device *input_device = NULL;
+	wl_list_for_each(input_device, &server.input->devices, link) {
+		input_manager_reset_input(input_device);
+	}
+}
+
+
 void input_manager_apply_seat_config(struct seat_config *seat_config) {
 	wlr_log(WLR_DEBUG, "applying seat config for seat %s", seat_config->name);
 	if (strcmp(seat_config->name, "*") == 0) {
diff --git a/sway/input/seat.c b/sway/input/seat.c
index a8df5b99..09acab0d 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -405,6 +405,14 @@ static void seat_update_capabilities(struct sway_seat *seat) {
 	}
 }
 
+static void seat_reset_input_config(struct sway_seat *seat,
+		struct sway_seat_device *sway_device) {
+	wlr_log(WLR_DEBUG, "Resetting output mapping for input device %s",
+		sway_device->input_device->identifier);
+	wlr_cursor_map_input_to_output(seat->cursor->cursor,
+		sway_device->input_device->wlr_device, NULL);
+}
+
 static void seat_apply_input_config(struct sway_seat *seat,
 		struct sway_seat_device *sway_device) {
 	const char *mapped_to_output = NULL;
@@ -522,6 +530,35 @@ void seat_configure_device(struct sway_seat *seat,
 	}
 }
 
+void seat_reset_device(struct sway_seat *seat,
+		struct sway_input_device *input_device) {
+	struct sway_seat_device *seat_device = seat_get_device(seat, input_device);
+	if (!seat_device) {
+		return;
+	}
+
+	switch (input_device->wlr_device->type) {
+		case WLR_INPUT_DEVICE_POINTER:
+			seat_reset_input_config(seat, seat_device);
+			break;
+		case WLR_INPUT_DEVICE_KEYBOARD:
+			sway_keyboard_configure(seat_device->keyboard);
+			break;
+		case WLR_INPUT_DEVICE_TOUCH:
+			seat_reset_input_config(seat, seat_device);
+			break;
+		case WLR_INPUT_DEVICE_TABLET_TOOL:
+			seat_reset_input_config(seat, seat_device);
+			break;
+		case WLR_INPUT_DEVICE_TABLET_PAD:
+			wlr_log(WLR_DEBUG, "TODO: reset tablet pad");
+			break;
+		case WLR_INPUT_DEVICE_SWITCH:
+			wlr_log(WLR_DEBUG, "TODO: reset switch device");
+			break;
+	}
+}
+
 void seat_add_device(struct sway_seat *seat,
 		struct sway_input_device *input_device) {
 	if (seat_get_device(seat, input_device)) {
-- 
cgit v1.2.3