wayland: Handle seat removal
Also, emit ::device-added and ::device-removed signals as devices appear and disappear.
This commit is contained in:
		| @ -30,7 +30,6 @@ | ||||
| #include "gdkkeysyms.h" | ||||
| #include "gdkdeviceprivate.h" | ||||
| #include "gdkdevicemanagerprivate.h" | ||||
| #include "gdkprivate-wayland.h" | ||||
|  | ||||
| #include <xkbcommon/xkbcommon.h> | ||||
| #include <X11/keysym.h> | ||||
| @ -46,6 +45,7 @@ typedef struct _GdkWaylandSelectionOffer GdkWaylandSelectionOffer; | ||||
|  | ||||
| struct _GdkWaylandDeviceData | ||||
| { | ||||
|   guint32 id; | ||||
|   struct wl_seat *wl_seat; | ||||
|   struct wl_pointer *wl_pointer; | ||||
|   struct wl_keyboard *wl_keyboard; | ||||
| @ -1128,6 +1128,8 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, | ||||
|  | ||||
|       device_manager->devices = | ||||
|         g_list_prepend (device_manager->devices, device->pointer); | ||||
|  | ||||
|       g_signal_emit_by_name (device_manager, "device-added", device->pointer); | ||||
|     } | ||||
|   else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && device->wl_pointer) | ||||
|     { | ||||
| @ -1137,11 +1139,12 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, | ||||
|       device_manager->devices = | ||||
|         g_list_remove (device_manager->devices, device->pointer); | ||||
|  | ||||
|       g_signal_emit_by_name (device_manager, "device-removed", device->pointer); | ||||
|       g_object_unref (device->pointer); | ||||
|       device->pointer = NULL; | ||||
|     } | ||||
|  | ||||
|   if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !device->wl_keyboard)  | ||||
|   if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !device->wl_keyboard) | ||||
|     { | ||||
|       device->wl_keyboard = wl_seat_get_keyboard(seat); | ||||
|       wl_keyboard_set_user_data(device->wl_keyboard, device); | ||||
| @ -1161,6 +1164,8 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, | ||||
|  | ||||
|       device_manager->devices = | ||||
|         g_list_prepend (device_manager->devices, device->keyboard); | ||||
|  | ||||
|       g_signal_emit_by_name (device_manager, "device-added", device->keyboard); | ||||
|     } | ||||
|   else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && device->wl_keyboard)  | ||||
|     { | ||||
| @ -1170,6 +1175,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, | ||||
|       device_manager->devices = | ||||
|         g_list_remove (device_manager->devices, device->keyboard); | ||||
|  | ||||
|       g_signal_emit_by_name (device_manager, "device-removed", device->keyboard); | ||||
|       g_object_unref (device->keyboard); | ||||
|       device->keyboard = NULL; | ||||
|     } | ||||
| @ -1181,8 +1187,10 @@ seat_handle_capabilities(void *data, struct wl_seat *seat, | ||||
|     } | ||||
|  | ||||
|   /* Once we have the capabilities event we know we have all events | ||||
|    * from the wl_seat and need no further init roundtrips. */ | ||||
|   display->init_ref_count--; | ||||
|    * from the wl_seat and need no further init roundtrips. | ||||
|    */ | ||||
|   if (display->init_ref_count > 0) | ||||
|     display->init_ref_count--; | ||||
| } | ||||
|  | ||||
| static const struct wl_seat_listener seat_listener = { | ||||
| @ -1205,8 +1213,9 @@ init_settings (GdkWaylandDeviceData *device) | ||||
| } | ||||
|  | ||||
| void | ||||
| _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, | ||||
| 					struct wl_seat *wl_seat) | ||||
| _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager, | ||||
|                                       guint32           id, | ||||
| 				      struct wl_seat   *wl_seat) | ||||
| { | ||||
|   GdkDisplay *display; | ||||
|   GdkWaylandDisplay *display_wayland; | ||||
| @ -1216,6 +1225,7 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, | ||||
|   display_wayland = GDK_WAYLAND_DISPLAY (display); | ||||
|  | ||||
|   device = g_new0 (GdkWaylandDeviceData, 1); | ||||
|   device->id = id; | ||||
|   device->keymap = _gdk_wayland_keymap_new (); | ||||
|   device->display = display; | ||||
|   device->device_manager = device_manager; | ||||
| @ -1237,6 +1247,32 @@ _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, | ||||
|   init_settings (device); | ||||
| } | ||||
|  | ||||
| void | ||||
| _gdk_wayland_device_manager_remove_seat (GdkDeviceManager *manager, | ||||
|                                          guint32           id) | ||||
| { | ||||
|   GdkWaylandDeviceManager *device_manager = GDK_WAYLAND_DEVICE_MANAGER (manager); | ||||
|   GList *l; | ||||
|  | ||||
|   for (l = device_manager->devices; l != NULL; l = l->next) | ||||
|     { | ||||
|       GdkWaylandDevice *wayland_device = l->data; | ||||
|       GdkWaylandDeviceData *device = wayland_device->device; | ||||
|  | ||||
|       if (device->id == id) | ||||
|         { | ||||
|           seat_handle_capabilities (device, device->wl_seat, 0); | ||||
|           g_object_unref (device->keymap); | ||||
|           wl_surface_destroy (device->pointer_surface); | ||||
|           /* FIXME: destroy data_device */ | ||||
|           g_clear_object (&device->keyboard_settings); | ||||
|           g_free (device); | ||||
|  | ||||
|           break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void | ||||
| free_device (gpointer data) | ||||
| { | ||||
|  | ||||
| @ -120,8 +120,7 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id | ||||
|     display_wayland->init_ref_count++; | ||||
|   } else if (strcmp(interface, "wl_seat") == 0) { | ||||
|     seat = wl_registry_bind(display_wayland->wl_registry, id, &wl_seat_interface, 1); | ||||
|     _gdk_wayland_device_manager_add_device (gdk_display->device_manager, | ||||
| 					    seat); | ||||
|     _gdk_wayland_device_manager_add_seat (gdk_display->device_manager, id, seat); | ||||
|     /* We need to roundtrip until we've received the wl_seat | ||||
|      * capabilities event which informs us of available input devices | ||||
|      * on this seat. */ | ||||
| @ -139,9 +138,10 @@ gdk_registry_handle_global_remove(void               *data, | ||||
|                                   uint32_t            id) | ||||
| { | ||||
|   GdkWaylandDisplay *display_wayland = data; | ||||
|   GdkDisplay *display = GDK_DISPLAY (display_wayland); | ||||
|  | ||||
|   /* We don't know what this item is - try as an output */ | ||||
|   _gdk_wayland_screen_remove_output_by_id (display_wayland->screen, id); | ||||
|   _gdk_wayland_device_manager_remove_seat (display->device_manager, id); | ||||
|   _gdk_wayland_screen_remove_output (display_wayland->screen, id); | ||||
|  | ||||
|   /* FIXME: the object needs to be destroyed here, we're leaking */ | ||||
| } | ||||
|  | ||||
| @ -132,8 +132,11 @@ gchar *     _gdk_wayland_display_utf8_to_string_target (GdkDisplay  *display, | ||||
| 							const gchar *str); | ||||
|  | ||||
| GdkDeviceManager *_gdk_wayland_device_manager_new (GdkDisplay *display); | ||||
| void              _gdk_wayland_device_manager_add_device (GdkDeviceManager *device_manager, | ||||
| 							  struct wl_seat *seat); | ||||
| void              _gdk_wayland_device_manager_add_seat (GdkDeviceManager *device_manager, | ||||
|                                                         guint32           id, | ||||
| 						        struct wl_seat   *seat); | ||||
| void              _gdk_wayland_device_manager_remove_seat (GdkDeviceManager *device_manager, | ||||
|                                                            guint32           id); | ||||
|  | ||||
| GdkKeymap *_gdk_wayland_device_get_keymap (GdkDevice *device); | ||||
|  | ||||
| @ -154,8 +157,8 @@ GdkScreen *_gdk_wayland_screen_new (GdkDisplay *display); | ||||
| void _gdk_wayland_screen_add_output (GdkScreen        *screen, | ||||
|                                      guint32           id, | ||||
|                                      struct wl_output *output); | ||||
| void _gdk_wayland_screen_remove_output_by_id (GdkScreen *screen, | ||||
|                                               guint32 id); | ||||
| void _gdk_wayland_screen_remove_output (GdkScreen *screen, | ||||
|                                         guint32 id); | ||||
|  | ||||
| void _gdk_wayland_display_manager_add_display (GdkDisplayManager *manager, | ||||
| 					       GdkDisplay        *display); | ||||
|  | ||||
| @ -952,8 +952,8 @@ _gdk_wayland_screen_add_output (GdkScreen        *screen, | ||||
| } | ||||
|  | ||||
| void | ||||
| _gdk_wayland_screen_remove_output_by_id (GdkScreen *screen, | ||||
|                                          guint32    id) | ||||
| _gdk_wayland_screen_remove_output (GdkScreen *screen, | ||||
|                                    guint32    id) | ||||
| { | ||||
|   GdkWaylandScreen *screen_wayland = GDK_WAYLAND_SCREEN (screen); | ||||
|   int i; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Matthias Clasen
					Matthias Clasen