[PATCH weston] input: Don't test keyboard/pointer/touch pointers

Derek Foreman derekf at osg.samsung.com
Thu Jan 29 09:39:55 PST 2015


Keyboards and pointers aren't freed when devices are removed,
so we should really be testing keyboard_device_count and
pointer_device_count in most cases, not the actual pointers.
Otherwise we end up with different behaviour after removing a
device than we had before it was inserted.

There are some cases (new device setup) where the pointers still
need to be tested directly.

Signed-off-by: Derek Foreman <derekf at osg.samsung.com>
---
 desktop-shell/shell.c               | 45 ++++++++++++++++++++-----------------
 fullscreen-shell/fullscreen-shell.c |  4 ++++
 src/compositor.c                    | 14 +++++++-----
 src/data-device.c                   | 10 ++++-----
 src/input.c                         | 24 ++++++++++----------
 src/libinput-seat.c                 |  2 +-
 src/screen-share.c                  |  2 +-
 src/screenshooter.c                 |  2 +-
 xwayland/window-manager.c           |  2 +-
 9 files changed, 57 insertions(+), 48 deletions(-)

diff --git a/desktop-shell/shell.c b/desktop-shell/shell.c
index f6d9c79..d5ac3c0 100644
--- a/desktop-shell/shell.c
+++ b/desktop-shell/shell.c
@@ -362,7 +362,7 @@ shell_grab_start(struct shell_grab *grab,
 	struct desktop_shell *shell = shsurf->shell;
 
 	popup_grab_end(pointer);
-	if (pointer->seat->touch)
+	if (pointer->seat->touch_device_count)
 		touch_popup_grab_end(pointer->seat->touch);
 
 	grab->grab.interface = interface;
@@ -529,7 +529,7 @@ shell_touch_grab_start(struct shell_touch_grab *grab,
 	struct desktop_shell *shell = shsurf->shell;
 
 	touch_popup_grab_end(touch);
-	if (touch->seat->pointer)
+	if (touch->seat->pointer_device_count)
 		popup_grab_end(touch->seat->pointer);
 
 	grab->grab.interface = interface;
@@ -893,7 +893,7 @@ restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
 		wl_list_insert(&shell->compositor->seat_list,
 			       &state->seat->link);
 
-		if (state->seat->keyboard == NULL)
+		if (!state->seat->keyboard_device_count)
 			continue;
 
 		surface = state->keyboard_focus;
@@ -906,7 +906,7 @@ restore_focus_state(struct desktop_shell *shell, struct workspace *ws)
 	wl_list_for_each_safe(seat, next_seat, &pending_seat_list, link) {
 		wl_list_insert(&shell->compositor->seat_list, &seat->link);
 
-		if (seat->keyboard == NULL)
+		if (!seat->keyboard_device_count)
 			continue;
 
 		weston_keyboard_set_focus(seat->keyboard, NULL);
@@ -1420,7 +1420,7 @@ move_surface_to_workspace(struct desktop_shell *shell,
 
 	drop_focus_state(shell, from, view->surface);
 	wl_list_for_each(seat, &shell->compositor->seat_list, link) {
-		if (!seat->keyboard)
+		if (!seat->keyboard_device_count)
 			continue;
 
 		focus = weston_surface_get_main_surface(seat->keyboard->focus);
@@ -1771,7 +1771,7 @@ common_surface_move(struct wl_resource *resource,
 	struct shell_surface *shsurf = wl_resource_get_user_data(resource);
 	struct weston_surface *surface;
 
-	if (seat->pointer &&
+	if (seat->pointer_device_count &&
 	    seat->pointer->focus &&
 	    seat->pointer->button_count > 0 &&
 	    seat->pointer->grab_serial == serial) {
@@ -1779,7 +1779,7 @@ common_surface_move(struct wl_resource *resource,
 		if ((surface == shsurf->surface) &&
 		    (surface_move(shsurf, seat, 1) < 0))
 			wl_resource_post_no_memory(resource);
-	} else if (seat->touch &&
+	} else if (seat->touch_device_count &&
 		   seat->touch->focus &&
 		   seat->touch->grab_serial == serial) {
 		surface = weston_surface_get_main_surface(seat->touch->focus->surface);
@@ -1971,7 +1971,7 @@ common_surface_resize(struct wl_resource *resource,
 	struct shell_surface *shsurf = wl_resource_get_user_data(resource);
 	struct weston_surface *surface;
 
-	if (seat->pointer == NULL ||
+	if (!seat->pointer_device_count ||
 	    seat->pointer->button_count == 0 ||
 	    seat->pointer->grab_serial != serial ||
 	    seat->pointer->focus == NULL)
@@ -2077,7 +2077,7 @@ end_busy_cursor(struct weston_compositor *compositor, struct wl_client *client)
 	struct weston_seat *seat;
 
 	wl_list_for_each(seat, &compositor->seat_list, link) {
-		if (seat->pointer == NULL)
+		if (!seat->pointer_device_count)
 			continue;
 
 		grab = (struct shell_grab *) seat->pointer->grab;
@@ -2102,7 +2102,7 @@ xdg_ping_timeout_handler(void *data)
 	/* Client is not responding */
 	sc->unresponsive = 1;
 	wl_list_for_each(seat, &sc->shell->compositor->seat_list, link) {
-		if (seat->pointer == NULL || seat->pointer->focus == NULL)
+		if (!seat->pointer_device_count || seat->pointer->focus == NULL)
 			continue;
 		if (seat->pointer->focus->surface->resource == NULL)
 			continue;
@@ -2661,7 +2661,7 @@ set_minimized(struct weston_surface *surface, uint32_t is_true)
 
 		drop_focus_state(shsurf->shell, current_ws, view->surface);
 		wl_list_for_each(seat, &shsurf->shell->compositor->seat_list, link) {
-			if (!seat->keyboard)
+			if (!seat->keyboard_device_count)
 				continue;
 			focus = weston_surface_get_main_surface(seat->keyboard->focus);
 			if (focus == view->surface)
@@ -2672,7 +2672,7 @@ set_minimized(struct weston_surface *surface, uint32_t is_true)
 		weston_layer_entry_insert(&current_ws->layer.view_list, &view->layer_link);
 
 		wl_list_for_each(seat, &shsurf->shell->compositor->seat_list, link) {
-			if (!seat->keyboard)
+			if (!seat->keyboard_device_count)
 				continue;
 			activate(shsurf->shell, view->surface, seat, true);
 		}
@@ -3041,6 +3041,9 @@ shell_seat_caps_changed(struct wl_listener *listener, void *data)
 
 	seat = container_of(listener, struct shell_seat, caps_changed_listener);
 
+	/* this is one of the few places where seat->keyboard and
+	 * seat->pointer should be tested directly, instead of
+	 * seat->*_device_count */
 	if (seat->seat->keyboard &&
 	    wl_list_empty(&seat->keyboard_focus_listener.link)) {
 		wl_signal_add(&seat->seat->keyboard->focus_signal,
@@ -3394,10 +3397,10 @@ shell_map_popup(struct shell_surface *shsurf)
 	weston_view_set_position(shsurf->view, shsurf->popup.x, shsurf->popup.y);
 	weston_view_update_transform(shsurf->view);
 
-	if (shseat->seat->pointer &&
+	if (shseat->seat->pointer_device_count &&
 	    shseat->seat->pointer->grab_serial == shsurf->popup.serial) {
 		add_popup_grab(shsurf, shseat, POINTER);
-	} else if (shseat->seat->touch &&
+	} else if (shseat->seat->touch_device_count &&
 	           shseat->seat->touch->grab_serial == shsurf->popup.serial) {
 		add_popup_grab(shsurf, shseat, TOUCH);
 	} else {
@@ -3617,11 +3620,11 @@ get_focused_output(struct weston_compositor *compositor)
 		 * three for loops and check frist for touch,
 		 * then for pointer, etc. but unless somebody has some
 		 * objections, I think this is sufficient. */
-		if (seat->touch && seat->touch->focus)
+		if (seat->touch_device_count && seat->touch->focus)
 			output = seat->touch->focus->output;
-		else if (seat->pointer && seat->pointer->focus)
+		else if (seat->pointer_device_count && seat->pointer->focus)
 			output = seat->pointer->focus->output;
-		else if (seat->keyboard && seat->keyboard->focus)
+		else if (seat->keyboard_device_count && seat->keyboard->focus)
 			output = seat->keyboard->focus->output;
 
 		if (output)
@@ -5040,7 +5043,7 @@ unfocus_all_seats(struct desktop_shell *shell)
 	struct weston_seat *seat, *next;
 
 	wl_list_for_each_safe(seat, next, &shell->compositor->seat_list, link) {
-		if (seat->keyboard == NULL)
+		if (!seat->keyboard_device_count)
 			continue;
 
 		weston_keyboard_set_focus(seat->keyboard, NULL);
@@ -5271,9 +5274,9 @@ idle_handler(struct wl_listener *listener, void *data)
 	struct weston_seat *seat;
 
 	wl_list_for_each(seat, &shell->compositor->seat_list, link) {
-		if (seat->pointer)
+		if (seat->pointer_device_count)
 			popup_grab_end(seat->pointer);
-		if (seat->touch)
+		if (seat->touch_device_count)
 			touch_popup_grab_end(seat->touch);
 	}
 
@@ -5322,7 +5325,7 @@ weston_view_set_initial_position(struct weston_view *view,
 	 * TODO: Do something clever for touch too?
 	 */
 	wl_list_for_each(seat, &compositor->seat_list, link) {
-		if (seat->pointer) {
+		if (seat->pointer_device_count) {
 			ix = wl_fixed_to_int(seat->pointer->x);
 			iy = wl_fixed_to_int(seat->pointer->y);
 			break;
diff --git a/fullscreen-shell/fullscreen-shell.c b/fullscreen-shell/fullscreen-shell.c
index 35e6d8f..38368b9 100644
--- a/fullscreen-shell/fullscreen-shell.c
+++ b/fullscreen-shell/fullscreen-shell.c
@@ -95,6 +95,10 @@ seat_caps_changed(struct wl_listener *l, void *data)
 	struct pointer_focus_listener *listener;
 	struct fs_output *fsout;
 
+	/* This function is one of the few places where seat->pointer and
+	 * seat->keyboard should be tested directly instead of
+	 * seat->*_device_count.
+	 */
 	listener = container_of(l, struct pointer_focus_listener, seat_caps);
 
 	/* no pointer */
diff --git a/src/compositor.c b/src/compositor.c
index c2c975d..84448f3 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -127,7 +127,7 @@ static void weston_mode_switch_finish(struct weston_output *output,
 		struct weston_pointer *pointer = seat->pointer;
 		int32_t x, y;
 
-		if (!pointer)
+		if (!seat->pointer_device_count)
 			continue;
 
 		x = wl_fixed_to_int(pointer->x);
@@ -1568,14 +1568,16 @@ weston_view_unmap(struct weston_view *view)
 		return;
 
 	wl_list_for_each(seat, &view->surface->compositor->seat_list, link) {
-		if (seat->keyboard && seat->keyboard->focus == view->surface)
+		if (seat->keyboard_device_count &&
+		    seat->keyboard->focus == view->surface)
 			weston_keyboard_set_focus(seat->keyboard, NULL);
-		if (seat->pointer && seat->pointer->focus == view)
+		if (seat->pointer_device_count &&
+		    seat->pointer->focus == view)
 			weston_pointer_set_focus(seat->pointer,
 						 NULL,
 						 wl_fixed_from_int(0),
 						 wl_fixed_from_int(0));
-		if (seat->touch && seat->touch->focus == view)
+		if (seat->touch_device_count && seat->touch->focus == view)
 			weston_touch_set_focus(seat, NULL);
 	}
 }
@@ -4249,7 +4251,7 @@ weston_compositor_set_default_pointer_grab(struct weston_compositor *ec,
 
 	ec->default_pointer_grab = interface;
 	wl_list_for_each(seat, &ec->seat_list, link) {
-		if (seat->pointer) {
+		if (seat->pointer_device_count) {
 			weston_pointer_set_default_grab(seat->pointer,
 							interface);
 		}
@@ -4964,7 +4966,7 @@ int main(int argc, char *argv[])
 	weston_config_section_get_bool(section, "numlock-on", &numlock_on, 0);
 	if (numlock_on) {
 		wl_list_for_each(seat, &ec->seat_list, link) {
-			if (seat->keyboard)
+			if (seat->keyboard_device_count)
 				weston_keyboard_set_locks(seat->keyboard,
 							  WESTON_NUM_LOCK,
 							  WESTON_NUM_LOCK);
diff --git a/src/data-device.c b/src/data-device.c
index a0913a2..8a5567e 100644
--- a/src/data-device.c
+++ b/src/data-device.c
@@ -664,13 +664,13 @@ data_device_start_drag(struct wl_client *client, struct wl_resource *resource,
 	int is_pointer_grab, is_touch_grab;
 	int32_t ret = 0;
 
-	is_pointer_grab = seat->pointer &&
+	is_pointer_grab = seat->pointer_device_count &&
 			  seat->pointer->button_count == 1 &&
 			  seat->pointer->grab_serial == serial &&
 			  seat->pointer->focus &&
 			  seat->pointer->focus->surface == origin;
 
-	is_touch_grab = seat->touch &&
+	is_touch_grab = seat->touch_device_count &&
 			seat->touch->num_tp == 1 &&
 			seat->touch->grab_serial == serial &&
 			seat->touch->focus &&
@@ -712,7 +712,7 @@ destroy_selection_data_source(struct wl_listener *listener, void *data)
 
 	seat->selection_data_source = NULL;
 
-	if (seat->keyboard)
+	if (seat->keyboard_device_count)
 		focus = seat->keyboard->focus;
 	if (focus && focus->resource) {
 		data_device = wl_resource_find_for_client(&seat->drag_resource_list,
@@ -744,7 +744,7 @@ weston_seat_set_selection(struct weston_seat *seat,
 	seat->selection_data_source = source;
 	seat->selection_serial = serial;
 
-	if (seat->keyboard)
+	if (seat->keyboard_device_count)
 		focus = seat->keyboard->focus;
 	if (focus && focus->resource) {
 		data_device = wl_resource_find_for_client(&seat->drag_resource_list,
@@ -914,7 +914,7 @@ wl_data_device_set_keyboard_focus(struct weston_seat *seat)
 	struct weston_data_source *source;
 	struct weston_surface *focus;
 
-	if (!seat->keyboard)
+	if (!seat->keyboard_device_count)
 		return;
 
 	focus = seat->keyboard->focus;
diff --git a/src/input.c b/src/input.c
index c039af0..b4f2ff7 100644
--- a/src/input.c
+++ b/src/input.c
@@ -51,7 +51,7 @@ weston_seat_repick(struct weston_seat *seat)
 {
 	const struct weston_pointer *pointer = seat->pointer;
 
-	if (pointer == NULL)
+	if (!seat->pointer_device_count)
 		return;
 
 	pointer->grab->interface->focus(seat->pointer->grab);
@@ -1001,7 +1001,7 @@ weston_surface_activate(struct weston_surface *surface,
 {
 	struct weston_compositor *compositor = seat->compositor;
 
-	if (seat->keyboard) {
+	if (seat->keyboard_device_count) {
 		weston_keyboard_set_focus(seat->keyboard, surface);
 		wl_data_device_set_keyboard_focus(seat);
 	}
@@ -1439,7 +1439,7 @@ notify_keyboard_focus_out(struct weston_seat *seat)
 
 	weston_keyboard_set_focus(keyboard, NULL);
 	weston_keyboard_cancel_grab(keyboard);
-	if (seat->pointer)
+	if (seat->pointer_device_count)
 		weston_pointer_cancel_grab(seat->pointer);
 }
 
@@ -1691,7 +1691,7 @@ seat_get_pointer(struct wl_client *client, struct wl_resource *resource,
 	struct weston_seat *seat = wl_resource_get_user_data(resource);
 	struct wl_resource *cr;
 
-	if (!seat->pointer)
+	if (!seat->pointer_device_count)
 		return;
 
         cr = wl_resource_create(client, &wl_pointer_interface,
@@ -1741,13 +1741,13 @@ static bool
 should_send_modifiers_to_client(struct weston_seat *seat,
 				struct wl_client *client)
 {
-	if (seat->keyboard &&
+	if (seat->keyboard_device_count &&
 	    seat->keyboard->focus &&
 	    seat->keyboard->focus->resource &&
 	    wl_resource_get_client(seat->keyboard->focus->resource) == client)
 		return true;
 
-	if (seat->pointer &&
+	if (seat->pointer_device_count &&
 	    seat->pointer->focus &&
 	    seat->pointer->focus->surface->resource &&
 	    wl_resource_get_client(seat->pointer->focus->surface->resource) == client)
@@ -1764,7 +1764,7 @@ seat_get_keyboard(struct wl_client *client, struct wl_resource *resource,
 	struct weston_keyboard *keyboard = seat->keyboard;
 	struct wl_resource *cr;
 
-	if (!seat->keyboard)
+	if (!seat->keyboard_device_count)
 		return;
 
         cr = wl_resource_create(client, &wl_keyboard_interface,
@@ -1843,7 +1843,7 @@ seat_get_touch(struct wl_client *client, struct wl_resource *resource,
 	struct weston_seat *seat = wl_resource_get_user_data(resource);
 	struct wl_resource *cr;
 
-	if (!seat->touch)
+	if (!seat->touch_device_count)
 		return;
 
         cr = wl_resource_create(client, &wl_touch_interface,
@@ -1884,11 +1884,11 @@ bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
 	wl_resource_set_implementation(resource, &seat_interface, data,
 				       unbind_resource);
 
-	if (seat->pointer)
+	if (seat->pointer_device_count)
 		caps |= WL_SEAT_CAPABILITY_POINTER;
-	if (seat->keyboard)
+	if (seat->keyboard_device_count)
 		caps |= WL_SEAT_CAPABILITY_KEYBOARD;
-	if (seat->touch)
+	if (seat->touch_device_count)
 		caps |= WL_SEAT_CAPABILITY_TOUCH;
 
 	wl_seat_send_capabilities(resource, caps);
@@ -2078,7 +2078,7 @@ weston_compositor_xkb_destroy(struct weston_compositor *ec)
 WL_EXPORT void
 weston_seat_update_keymap(struct weston_seat *seat, struct xkb_keymap *keymap)
 {
-	if (!seat->keyboard || !keymap)
+	if (!seat->keyboard_device_count || !keymap)
 		return;
 
 #ifdef ENABLE_XKBCOMMON
diff --git a/src/libinput-seat.c b/src/libinput-seat.c
index ef2d804..9b19e55 100644
--- a/src/libinput-seat.c
+++ b/src/libinput-seat.c
@@ -73,7 +73,7 @@ device_added(struct udev_input *input, struct libinput_device *libinput_device)
 	udev_seat = (struct udev_seat *) seat;
 	wl_list_insert(udev_seat->devices_list.prev, &device->link);
 
-	if (seat->output && seat->pointer)
+	if (seat->output && seat->pointer_device_count)
 		weston_pointer_clamp(seat->pointer,
 				     &seat->pointer->x,
 				     &seat->pointer->y);
diff --git a/src/screen-share.c b/src/screen-share.c
index 524a0ca..b5e9d35 100644
--- a/src/screen-share.c
+++ b/src/screen-share.c
@@ -1068,7 +1068,7 @@ share_output_binding(struct weston_seat *seat, uint32_t time, uint32_t key,
 	struct weston_output *output;
 	struct screen_share *ss = data;
 
-	if (!seat->pointer) {
+	if (!seat->pointer_device_count) {
 		weston_log("Cannot pick output: Seat does not have pointer\n");
 		return;
 	}
diff --git a/src/screenshooter.c b/src/screenshooter.c
index c98e2f9..23e77eb 100644
--- a/src/screenshooter.c
+++ b/src/screenshooter.c
@@ -583,7 +583,7 @@ recorder_binding(struct weston_seat *seat, uint32_t time, uint32_t key, void *da
 		recorder->destroying = 1;
 		weston_output_schedule_repaint(recorder->output);
 	} else {
-		if (seat->keyboard && seat->keyboard->focus &&
+		if (seat->keyboard_device_count && seat->keyboard->focus &&
 		    seat->keyboard->focus->output)
 			output = seat->keyboard->focus->output;
 		else
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 4d3611f..f253cc6 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -1241,7 +1241,7 @@ weston_wm_pick_seat_for_window(struct weston_wm_window *window)
 
 	seat = NULL;
 	wl_list_for_each(s, &wm->server->compositor->seat_list, link) {
-		if (s->pointer != NULL && s->pointer->focus &&
+		if (!s->pointer_device_count && s->pointer->focus &&
 		    s->pointer->focus->surface == window->surface &&
 		    s->pointer->button_count > 0 &&
 		    (seat == NULL ||
-- 
2.1.4



More information about the wayland-devel mailing list