diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c index 566a59693..2159cce74 100644 --- a/src/wayland/meta-wayland-keyboard.c +++ b/src/wayland/meta-wayland-keyboard.c @@ -225,13 +225,25 @@ err_keymap_str: return; } +static void +release_focus (MetaWaylandKeyboard *keyboard) +{ + keyboard->focus_resource = NULL; + keyboard->focus_surface = NULL; +} + static void keyboard_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_surface_listener); + release_focus (keyboard); +} - keyboard->focus_resource = NULL; - keyboard->focus = NULL; +static void +keyboard_handle_focus_resource_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandKeyboard *keyboard = wl_container_of (listener, keyboard, focus_resource_listener); + release_focus (keyboard); } static gboolean @@ -287,10 +299,9 @@ default_grab_modifiers (MetaWaylandKeyboardGrab *grab, uint32_t serial, wl_keyboard_send_modifiers (resource, serial, mods_depressed, mods_latched, mods_locked, group); - if (pointer && pointer->focus && pointer->focus != keyboard->focus) + if (pointer && pointer->focus_surface && pointer->focus_surface != keyboard->focus_surface) { - pr = find_resource_for_surface (&keyboard->resource_list, - pointer->focus); + pr = find_resource_for_surface (&keyboard->resource_list, pointer->focus_surface); if (pr) { wl_keyboard_send_modifiers (pr, serial, @@ -342,7 +353,10 @@ meta_wayland_keyboard_init (MetaWaylandKeyboard *keyboard, wl_list_init (&keyboard->resource_list); wl_array_init (&keyboard->keys); + keyboard->focus_surface_listener.notify = keyboard_handle_focus_surface_destroy; + keyboard->focus_resource_listener.notify = keyboard_handle_focus_resource_destroy; + keyboard->default_grab.interface = &default_keyboard_grab_interface; keyboard->default_grab.keyboard = keyboard; keyboard->grab = &keyboard->default_grab; @@ -513,19 +527,27 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, struct wl_resource *resource; uint32_t serial; - if (keyboard->focus == surface && keyboard->focus_resource != NULL) + if (keyboard->focus_surface == surface && keyboard->focus_resource != NULL) return; resource = keyboard->focus_resource; - if (keyboard->focus_resource && keyboard->focus->resource) + if (resource) { - struct wl_client *client = wl_resource_get_client (resource); - struct wl_display *display = wl_client_get_display (client); - serial = wl_display_next_serial (display); - wl_keyboard_send_leave (resource, serial, keyboard->focus->resource); + if (keyboard->focus_surface->resource) + { + struct wl_client *client = wl_resource_get_client (resource); + struct wl_display *display = wl_client_get_display (client); + serial = wl_display_next_serial (display); + wl_keyboard_send_leave (resource, serial, keyboard->focus_surface->resource); + + meta_wayland_surface_focused_unset (keyboard->focus_surface); + } + + wl_list_remove (&keyboard->focus_resource_listener.link); wl_list_remove (&keyboard->focus_surface_listener.link); - meta_wayland_surface_focused_unset (keyboard->focus); + keyboard->focus_resource = NULL; + keyboard->focus_surface = NULL; } resource = find_resource_for_surface (&keyboard->resource_list, surface); @@ -558,14 +580,17 @@ meta_wayland_keyboard_set_focus (MetaWaylandKeyboard *keyboard, wl_keyboard_send_enter (resource, serial, surface->resource, &keyboard->keys); } - wl_resource_add_destroy_listener (surface->resource, &keyboard->focus_surface_listener); - keyboard->focus_serial = serial; meta_wayland_surface_focused_set (surface); - } - keyboard->focus_resource = resource; - keyboard->focus = surface; + keyboard->focus_resource = resource; + keyboard->focus_surface = surface; + + wl_resource_add_destroy_listener (keyboard->focus_resource, &keyboard->focus_resource_listener); + wl_resource_add_destroy_listener (keyboard->focus_surface->resource, &keyboard->focus_surface_listener); + + keyboard->focus_serial = serial; + } } void @@ -591,8 +616,6 @@ meta_wayland_keyboard_release (MetaWaylandKeyboard *keyboard) xkb_context_unref (keyboard->xkb_context); /* XXX: What about keyboard->resource_list? */ - if (keyboard->focus_resource) - wl_list_remove (&keyboard->focus_surface_listener.link); wl_array_release (&keyboard->keys); } @@ -611,7 +634,7 @@ meta_wayland_keyboard_begin_modal (MetaWaylandKeyboard *keyboard, if (keyboard->grab != &keyboard->default_grab) return FALSE; - if (keyboard->focus) + if (keyboard->focus_surface) { /* Fake key release events for the focused app */ serial = wl_display_next_serial (keyboard->display); @@ -653,7 +676,7 @@ meta_wayland_keyboard_end_modal (MetaWaylandKeyboard *keyboard, meta_wayland_keyboard_end_grab (keyboard); g_slice_free (MetaWaylandKeyboardGrab, grab); - if (keyboard->focus) + if (keyboard->focus_surface) { /* Fake key press events for the focused app */ serial = wl_display_next_serial (keyboard->display); diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h index fd87c8643..b51d3c02a 100644 --- a/src/wayland/meta-wayland-keyboard.h +++ b/src/wayland/meta-wayland-keyboard.h @@ -92,9 +92,11 @@ typedef struct struct _MetaWaylandKeyboard { struct wl_list resource_list; - MetaWaylandSurface *focus; - struct wl_resource *focus_resource; + + MetaWaylandSurface *focus_surface; struct wl_listener focus_surface_listener; + struct wl_resource *focus_resource; + struct wl_listener focus_resource_listener; uint32_t focus_serial; MetaWaylandKeyboardGrab *grab; diff --git a/src/wayland/meta-wayland-pointer.c b/src/wayland/meta-wayland-pointer.c index 59ed0934e..035ceabd9 100644 --- a/src/wayland/meta-wayland-pointer.c +++ b/src/wayland/meta-wayland-pointer.c @@ -63,13 +63,25 @@ meta_wayland_pointer_get_seat (MetaWaylandPointer *pointer) return seat; } +static void +release_focus (MetaWaylandPointer *pointer) +{ + pointer->focus_resource = NULL; + pointer->focus_surface = NULL; +} + static void pointer_handle_focus_surface_destroy (struct wl_listener *listener, void *data) { MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_surface_listener); + release_focus (pointer); +} - pointer->focus_resource = NULL; - pointer->focus = NULL; +static void +pointer_handle_focus_resource_destroy (struct wl_listener *listener, void *data) +{ + MetaWaylandPointer *pointer = wl_container_of (listener, pointer, focus_resource_listener); + release_focus (pointer); } static void @@ -97,7 +109,7 @@ default_grab_motion (MetaWaylandPointerGrab *grab, wl_fixed_t sx, sy; meta_wayland_pointer_get_relative_coordinates (grab->pointer, - grab->pointer->focus, + grab->pointer->focus_surface, &sx, &sy); wl_pointer_send_motion (resource, clutter_event_get_time (event), sx, sy); } @@ -265,7 +277,10 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer) memset (pointer, 0, sizeof *pointer); wl_list_init (&pointer->resource_list); + pointer->focus_surface_listener.notify = pointer_handle_focus_surface_destroy; + pointer->focus_resource_listener.notify = pointer_handle_focus_resource_destroy; + pointer->default_grab.interface = &default_pointer_grab_interface; pointer->default_grab.pointer = pointer; pointer->grab = &pointer->default_grab; @@ -292,12 +307,7 @@ meta_wayland_pointer_init (MetaWaylandPointer *pointer) void meta_wayland_pointer_release (MetaWaylandPointer *pointer) { - /* XXX: What about pointer->resource_list? */ - if (pointer->focus_resource) - wl_list_remove (&pointer->focus_surface_listener.link); - - pointer->focus = NULL; - pointer->focus_resource = NULL; + release_focus (pointer); } static struct wl_resource * @@ -323,21 +333,25 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, struct wl_resource *resource, *kr; uint32_t serial; - if (pointer->focus == surface && pointer->focus_resource != NULL) + if (pointer->focus_surface == surface && pointer->focus_resource != NULL) return; resource = pointer->focus_resource; if (resource) { - if (pointer->focus->resource) + if (pointer->focus_surface->resource) { struct wl_client *client = wl_resource_get_client (resource); struct wl_display *display = wl_client_get_display (client); serial = wl_display_next_serial (display); - wl_pointer_send_leave (resource, serial, pointer->focus->resource); + wl_pointer_send_leave (resource, serial, pointer->focus_surface->resource); } wl_list_remove (&pointer->focus_surface_listener.link); + wl_list_remove (&pointer->focus_resource_listener.link); + + pointer->focus_surface = NULL; + pointer->focus_resource = NULL; } resource = find_resource_for_surface (&pointer->resource_list, surface); @@ -370,12 +384,15 @@ meta_wayland_pointer_set_focus (MetaWaylandPointer *pointer, wl_fixed_to_int (pointer->x), wl_fixed_to_int (pointer->y)); wl_pointer_send_enter (resource, serial, surface->resource, sx, sy); - wl_resource_add_destroy_listener (surface->resource, &pointer->focus_surface_listener); + + pointer->focus_resource = resource; + pointer->focus_surface = surface; + + wl_resource_add_destroy_listener (pointer->focus_resource, &pointer->focus_resource_listener); + wl_resource_add_destroy_listener (pointer->focus_surface->resource, &pointer->focus_surface_listener); + pointer->focus_serial = serial; } - - pointer->focus_resource = resource; - pointer->focus = surface; } void diff --git a/src/wayland/meta-wayland-pointer.h b/src/wayland/meta-wayland-pointer.h index e5ee4c1c5..7fa9bf583 100644 --- a/src/wayland/meta-wayland-pointer.h +++ b/src/wayland/meta-wayland-pointer.h @@ -46,9 +46,11 @@ struct _MetaWaylandPointerGrab struct _MetaWaylandPointer { struct wl_list resource_list; - MetaWaylandSurface *focus; - struct wl_resource *focus_resource; + + MetaWaylandSurface *focus_surface; struct wl_listener focus_surface_listener; + struct wl_resource *focus_resource; + struct wl_listener focus_resource_listener; guint32 focus_serial; guint32 click_serial; diff --git a/src/wayland/meta-wayland-seat.c b/src/wayland/meta-wayland-seat.c index 9e838f90f..ff6f57de6 100644 --- a/src/wayland/meta-wayland-seat.c +++ b/src/wayland/meta-wayland-seat.c @@ -95,9 +95,9 @@ pointer_set_cursor (struct wl_client *client, surface = (surface_resource ? wl_resource_get_user_data (surface_resource) : NULL); - if (seat->pointer.focus == NULL) + if (seat->pointer.focus_surface == NULL) return; - if (wl_resource_get_client (seat->pointer.focus->resource) != client) + if (wl_resource_get_client (seat->pointer.focus_surface->resource) != client) return; if (seat->pointer.focus_serial - serial > G_MAXUINT32 / 2) return; @@ -125,9 +125,9 @@ seat_get_pointer (struct wl_client *client, wl_resource_set_implementation (cr, &pointer_interface, seat, unbind_resource); wl_list_insert (&seat->pointer.resource_list, wl_resource_get_link (cr)); - if (seat->pointer.focus && - wl_resource_get_client (seat->pointer.focus->resource) == client) - meta_wayland_pointer_set_focus (&seat->pointer, seat->pointer.focus); + if (seat->pointer.focus_surface && + wl_resource_get_client (seat->pointer.focus_surface->resource) == client) + meta_wayland_pointer_set_focus (&seat->pointer, seat->pointer.focus_surface); } static void @@ -148,10 +148,10 @@ seat_get_keyboard (struct wl_client *client, seat->keyboard.xkb_info.keymap_fd, seat->keyboard.xkb_info.keymap_size); - if (seat->keyboard.focus && - wl_resource_get_client (seat->keyboard.focus->resource) == client) + if (seat->keyboard.focus_surface && + wl_resource_get_client (seat->keyboard.focus_surface->resource) == client) { - meta_wayland_keyboard_set_focus (&seat->keyboard, seat->keyboard.focus); + meta_wayland_keyboard_set_focus (&seat->keyboard, seat->keyboard.focus_surface); meta_wayland_data_device_set_keyboard_focus (seat); } } @@ -429,7 +429,7 @@ meta_wayland_seat_repick (MetaWaylandSeat *seat, } pointer->current = surface; - if (surface != pointer->focus) + if (surface != pointer->focus_surface) { const MetaWaylandPointerGrabInterface *interface = pointer->grab->interface; diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c index 12bb3d000..192e6e3b6 100644 --- a/src/wayland/meta-wayland-surface.c +++ b/src/wayland/meta-wayland-surface.c @@ -826,7 +826,7 @@ xdg_surface_move (struct wl_client *client, if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || - seat->pointer.focus != surface) + seat->pointer.focus_surface != surface) return; begin_grab_op_on_surface (surface, seat, META_GRAB_OP_MOVING); @@ -872,7 +872,7 @@ xdg_surface_resize (struct wl_client *client, if (seat->pointer.button_count == 0 || seat->pointer.grab_serial != serial || - seat->pointer.focus != surface) + seat->pointer.focus_surface != surface) return; begin_grab_op_on_surface (surface, seat, grab_op_for_edge (edges));