Support wl_keyboard::modifiers event

This event lets the compositor inform clients of the canonical keyboard
modifier/group state.  Make sure we send it at appropriate moments from
the compositor, and listen for it in clients as well.

Signed-off-by: Daniel Stone <daniel@fooishbar.org>
diff --git a/src/compositor.c b/src/compositor.c
index c562546..bfca256 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -1654,6 +1654,15 @@
 	wl_keyboard_set_focus(seat->seat.keyboard, &surface->surface);
 	wl_data_device_set_keyboard_focus(&seat->seat);
 
+	if (seat->seat.keyboard->focus_resource) {
+		wl_keyboard_send_modifiers(seat->seat.keyboard->focus_resource,
+					   wl_display_next_serial(compositor->wl_display),
+					   compositor->xkb_info.mods_depressed,
+					   compositor->xkb_info.mods_latched,
+					   compositor->xkb_info.mods_locked,
+					   compositor->xkb_info.group);
+	}
+
 	wl_signal_emit(&compositor->activate_signal, surface);
 }
 
@@ -1822,6 +1831,13 @@
 					      time, key, 0, 0, state);
 
 	grab->interface->key(grab, time, key, state);
+	if (mods)
+		grab->interface->modifiers(grab,
+					   wl_display_get_serial(compositor->wl_display),
+					   compositor->xkb_info.mods_depressed,
+					   compositor->xkb_info.mods_latched,
+					   compositor->xkb_info.mods_locked,
+					   compositor->xkb_info.group);
 }
 
 WL_EXPORT void
@@ -1878,6 +1894,15 @@
 		if (surface) {
 			wl_list_remove(&ws->saved_kbd_focus_listener.link);
 			wl_keyboard_set_focus(ws->seat.keyboard, surface);
+
+			if (seat->keyboard->focus_resource) {
+				wl_keyboard_send_modifiers(seat->keyboard->focus_resource,
+							   wl_display_next_serial(compositor->wl_display),
+							   compositor->xkb_info.mods_depressed,
+							   compositor->xkb_info.mods_latched,
+							   compositor->xkb_info.mods_locked,
+							   compositor->xkb_info.group);
+			}
 			ws->saved_kbd_focus = NULL;
 		}
 	} else {